@xyflow/vue 2.0.0-next.3 → 2.0.0-next.5

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.js CHANGED
@@ -22,12 +22,14 @@ let ErrorCode = /* @__PURE__ */ function(ErrorCode) {
22
22
  ErrorCode["NODE_MISSING_PARENT"] = "NODE_MISSING_PARENT";
23
23
  ErrorCode["NODE_TYPE_MISSING"] = "NODE_TYPE_MISSING";
24
24
  ErrorCode["NODE_EXTENT_INVALID"] = "NODE_EXTENT_INVALID";
25
+ ErrorCode["NODE_DUPLICATE_ID"] = "NODE_DUPLICATE_ID";
25
26
  ErrorCode["EDGE_INVALID"] = "EDGE_INVALID";
26
27
  ErrorCode["EDGE_NOT_FOUND"] = "EDGE_NOT_FOUND";
27
28
  ErrorCode["EDGE_SOURCE_MISSING"] = "EDGE_SOURCE_MISSING";
28
29
  ErrorCode["EDGE_TARGET_MISSING"] = "EDGE_TARGET_MISSING";
29
30
  ErrorCode["EDGE_TYPE_MISSING"] = "EDGE_TYPE_MISSING";
30
31
  ErrorCode["EDGE_SOURCE_TARGET_MISSING"] = "EDGE_SOURCE_TARGET_MISSING";
32
+ ErrorCode["EDGE_DUPLICATE_ID"] = "EDGE_DUPLICATE_ID";
31
33
  ErrorCode["USE_VUE_FLOW_OUTSIDE_PROVIDER"] = "USE_VUE_FLOW_OUTSIDE_PROVIDER";
32
34
  return ErrorCode;
33
35
  }({});
@@ -39,11 +41,13 @@ const messages = {
39
41
  ["NODE_MISSING_PARENT"]: (id, parentId) => `Node is missing a parent\nNode id: ${id}\nParent id: ${parentId}`,
40
42
  ["NODE_TYPE_MISSING"]: (type) => `Node type is missing\nType: ${type}`,
41
43
  ["NODE_EXTENT_INVALID"]: (id) => `Only child nodes can use a parent extent\nNode id: ${id}`,
44
+ ["NODE_DUPLICATE_ID"]: (id) => `Node id is not unique — a later node overwrites the earlier one in the lookup\nNode id: ${id}`,
42
45
  ["EDGE_INVALID"]: (id) => `An edge needs a source and a target\nEdge id: ${id}`,
43
46
  ["EDGE_SOURCE_MISSING"]: (id, source) => `Edge source is missing\nEdge id: ${id} \nSource id: ${source}`,
44
47
  ["EDGE_TARGET_MISSING"]: (id, target) => `Edge target is missing\nEdge id: ${id} \nTarget id: ${target}`,
45
48
  ["EDGE_TYPE_MISSING"]: (type) => `Edge type is missing\nType: ${type}`,
46
49
  ["EDGE_SOURCE_TARGET_MISSING"]: (id, source, target) => `Edge source or target is missing\nEdge id: ${id} \nSource id: ${source} \nTarget id: ${target}`,
50
+ ["EDGE_DUPLICATE_ID"]: (id) => `Edge id is not unique — a later edge overwrites the earlier one in the lookup\nEdge id: ${id}`,
47
51
  ["EDGE_NOT_FOUND"]: (id) => `Edge not found\nEdge id: ${id}`,
48
52
  ["USE_VUE_FLOW_OUTSIDE_PROVIDER"]: () => `useVueFlow() was called without a <VueFlow> or <VueFlowProvider> ancestor (or outside a component setup). Render one of them above the call, or wrap your components in <VueFlowProvider> to share a store.`
49
53
  };
@@ -111,7 +115,7 @@ var export_helper_default = (sfc, props) => {
111
115
  };
112
116
  //#endregion
113
117
  //#region src/components/Background/Background.vue
114
- const _sfc_main$24 = /* @__PURE__ */ (0, vue.defineComponent)({
118
+ const _sfc_main$25 = /* @__PURE__ */ (0, vue.defineComponent)({
115
119
  name: "Background",
116
120
  compatConfig: { MODE: 3 },
117
121
  props: {
@@ -196,7 +200,7 @@ const _sfc_main$24 = /* @__PURE__ */ (0, vue.defineComponent)({
196
200
  return __returned__;
197
201
  }
198
202
  });
199
- const _hoisted_1$14 = { class: "vue-flow__background vue-flow__container" };
203
+ const _hoisted_1$15 = { class: "vue-flow__background vue-flow__container" };
200
204
  const _hoisted_2$4 = [
201
205
  "id",
202
206
  "x",
@@ -210,8 +214,8 @@ const _hoisted_3$3 = [
210
214
  "y",
211
215
  "fill"
212
216
  ];
213
- function _sfc_render$24(_ctx, _cache, $props, $setup, $data, $options) {
214
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_1$14, [
217
+ function _sfc_render$25(_ctx, _cache, $props, $setup, $data, $options) {
218
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_1$15, [
215
219
  (0, vue.renderSlot)(_ctx.$slots, "pattern-container", { id: $setup.patternId }, () => [(0, vue.createElementVNode)("pattern", {
216
220
  id: $setup.patternId,
217
221
  x: $setup.viewport.x % $setup.background.scaledGap[0],
@@ -244,10 +248,10 @@ function _sfc_render$24(_ctx, _cache, $props, $setup, $data, $options) {
244
248
  (0, vue.renderSlot)(_ctx.$slots, "default", { id: $setup.patternId })
245
249
  ]);
246
250
  }
247
- var Background_default = /* @__PURE__ */ export_helper_default(_sfc_main$24, [["render", _sfc_render$24], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Background/Background.vue"]]);
251
+ var Background_default = /* @__PURE__ */ export_helper_default(_sfc_main$25, [["render", _sfc_render$25], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Background/Background.vue"]]);
248
252
  //#endregion
249
253
  //#region src/components/Controls/ControlButton.vue
250
- const _sfc_main$23 = /* @__PURE__ */ (0, vue.defineComponent)({
254
+ const _sfc_main$24 = /* @__PURE__ */ (0, vue.defineComponent)({
251
255
  name: "ControlButton",
252
256
  compatConfig: { MODE: 3 },
253
257
  props: {
@@ -271,12 +275,12 @@ const _sfc_main$23 = /* @__PURE__ */ (0, vue.defineComponent)({
271
275
  return __returned__;
272
276
  }
273
277
  });
274
- const _hoisted_1$13 = [
278
+ const _hoisted_1$14 = [
275
279
  "disabled",
276
280
  "aria-label",
277
281
  "title"
278
282
  ];
279
- function _sfc_render$23(_ctx, _cache, $props, $setup, $data, $options) {
283
+ function _sfc_render$24(_ctx, _cache, $props, $setup, $data, $options) {
280
284
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
281
285
  type: "button",
282
286
  class: "vue-flow__controls-button",
@@ -284,9 +288,9 @@ function _sfc_render$23(_ctx, _cache, $props, $setup, $data, $options) {
284
288
  "aria-label": $props.label,
285
289
  title: $props.label,
286
290
  onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("click", $event))
287
- }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 8, _hoisted_1$13);
291
+ }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 8, _hoisted_1$14);
288
292
  }
289
- var ControlButton_default = /* @__PURE__ */ export_helper_default(_sfc_main$23, [["render", _sfc_render$23], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Controls/ControlButton.vue"]]);
293
+ var ControlButton_default = /* @__PURE__ */ export_helper_default(_sfc_main$24, [["render", _sfc_render$24], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Controls/ControlButton.vue"]]);
290
294
  //#endregion
291
295
  //#region src/composables/storeToRefs.ts
292
296
  /**
@@ -315,7 +319,7 @@ function storeToRefs(store) {
315
319
  * @param params
316
320
  */
317
321
  function useDrag(params) {
318
- const { panBy, getInternalNode, removeSelectedNodes, removeSelectedEdges, updateNodePositions, getNodes, getEdges } = useVueFlow();
322
+ const { panBy, getInternalNode, addSelectedNodes, removeSelectedNodes, removeSelectedEdges, updateNodePositions, getNodes, getEdges } = useVueFlow();
319
323
  const store = useStore();
320
324
  const { nodeLookup } = store;
321
325
  const { onStart, onDrag, onStop, onClick, el, disabled, id, selectable, dragHandle } = params;
@@ -387,6 +391,13 @@ function useDrag(params) {
387
391
  },
388
392
  autoPanSpeed: store.autoPanSpeed
389
393
  }),
394
+ onNodeMouseDown: (nodeId) => {
395
+ const node = getInternalNode(nodeId);
396
+ if (!node) return;
397
+ store.nodesSelectionActive = false;
398
+ if (!node.selected) addSelectedNodes([node]);
399
+ else if (store.multiSelectionActive) removeSelectedNodes([node]);
400
+ },
390
401
  onDragStart: (event, _dragItems, node, nodes) => {
391
402
  dragFired = true;
392
403
  dragging.value = true;
@@ -826,12 +837,15 @@ function reconnectEdgeAction(edge, newConnection, prevEdge, shouldReplaceId, tri
826
837
  */
827
838
  function adoptNodes(nodes, nodeLookup, parentLookup, triggerError, options) {
828
839
  const validNodes = [];
840
+ const seenNodeIds = /* @__PURE__ */ new Set();
829
841
  for (let i = 0; i < nodes.length; ++i) {
830
842
  const node = nodes[i];
831
843
  if (!isNode(node)) {
832
844
  triggerError(new VueFlowError("NODE_INVALID", node?.id ?? `[ID UNKNOWN|INDEX ${i}]`));
833
845
  continue;
834
846
  }
847
+ if (seenNodeIds.has(node.id)) triggerError(new VueFlowError("NODE_DUPLICATE_ID", node.id));
848
+ else seenNodeIds.add(node.id);
835
849
  validNodes.push((0, vue.markRaw)((0, vue.toRaw)(node)));
836
850
  }
837
851
  const priorInternals = /* @__PURE__ */ new Map();
@@ -1554,9 +1568,10 @@ function useViewportHelper(state, nodeLookup) {
1554
1568
  /**
1555
1569
  * Two-way bind a `v-model` array ref to the store, identity-in / snapshot-out, with native `watch`.
1556
1570
  *
1557
- * Used only when `<VueFlow>` does NOT own its store (it reuses a `<VueFlowProvider>`'s), so the model
1558
- * refs can't back the store directly. The owned-store path is single-source instead the model refs
1559
- * ARE the store's nodes/edges (see `createStore`'s `StoreSignals` binding), needing no sync here.
1571
+ * Runs for BOTH the owned- and reused-store paths: the store's canonical nodes/edges are always an
1572
+ * internal `shallowRef` (see `createStore`), never the v-model ref, so this is the single place the model
1573
+ * ref is bridged to the store. Both directions flush synchronously so the model ref and the store's
1574
+ * synchronous reads (`getNodes`/`state.nodes`) never disagree within a tick.
1560
1575
  *
1561
1576
  * - **out** (store → model): snapshot on every membership change; element refs are shared, so per-node
1562
1577
  * field mutations surface without a copy.
@@ -1569,24 +1584,29 @@ function syncModelArray(model, storeItems, setItems) {
1569
1584
  (0, vue.watch)([storeItems, () => storeItems.value.length], () => {
1570
1585
  lastSnapshot = [...storeItems.value];
1571
1586
  model.value = lastSnapshot;
1572
- }, { immediate: storeItems.value.length > 0 });
1587
+ }, {
1588
+ immediate: storeItems.value.length > 0,
1589
+ flush: "sync"
1590
+ });
1573
1591
  (0, vue.watch)([model, () => model.value?.length], ([next]) => {
1574
1592
  if (!Array.isArray(next)) return;
1575
1593
  const nextRaw = (0, vue.toRaw)(next);
1576
1594
  if (nextRaw === lastSnapshot) return;
1577
1595
  setItems(nextRaw);
1578
- }, { immediate: true });
1596
+ }, {
1597
+ immediate: true,
1598
+ flush: "sync"
1599
+ });
1579
1600
  }
1580
1601
  /**
1581
1602
  * Watches props and updates the store accordingly
1582
1603
  *
1583
1604
  * @internal
1584
- * @param models v-model refs for nodes/edges (bound only when `ownsStore` is false see {@link syncModelArray})
1605
+ * @param models v-model refs for nodes/edges bridged to the store here (see {@link syncModelArray})
1585
1606
  * @param props the `<VueFlow>` props
1586
1607
  * @param handle the created store handle ({@link VueFlowStoreHandle}) — instance (actions) + reactive state
1587
- * @param ownsStore whether this `<VueFlow>` created the store (then nodes/edges are signal-backed and skipped here)
1588
1608
  */
1589
- function useWatchProps(models, props, handle, ownsStore = false) {
1609
+ function useWatchProps(models, props, handle) {
1590
1610
  const { instance, state } = handle;
1591
1611
  const storeRefs = storeToRefs(state);
1592
1612
  const scope = (0, vue.effectScope)(true);
@@ -1690,10 +1710,8 @@ function useWatchProps(models, props, handle, ownsStore = false) {
1690
1710
  }
1691
1711
  };
1692
1712
  const runAll = () => {
1693
- if (!ownsStore) {
1694
- watchNodesValue();
1695
- watchEdgesValue();
1696
- }
1713
+ watchNodesValue();
1714
+ watchEdgesValue();
1697
1715
  watchMinZoom();
1698
1716
  watchMaxZoom();
1699
1717
  watchTranslateExtent();
@@ -1709,13 +1727,14 @@ function useWatchProps(models, props, handle, ownsStore = false) {
1709
1727
  }
1710
1728
  //#endregion
1711
1729
  //#region src/components/Panel/Panel.vue
1712
- const _sfc_main$22 = /* @__PURE__ */ (0, vue.defineComponent)({
1730
+ const _sfc_main$23 = /* @__PURE__ */ (0, vue.defineComponent)({
1713
1731
  name: "Panel",
1714
1732
  compatConfig: { MODE: 3 },
1715
1733
  props: {
1716
1734
  position: {
1717
1735
  type: String,
1718
- required: true
1736
+ required: false,
1737
+ default: "top-left"
1719
1738
  },
1720
1739
  label: {
1721
1740
  type: [String, null],
@@ -1738,15 +1757,15 @@ const _sfc_main$22 = /* @__PURE__ */ (0, vue.defineComponent)({
1738
1757
  return __returned__;
1739
1758
  }
1740
1759
  });
1741
- const _hoisted_1$12 = ["aria-label"];
1742
- function _sfc_render$22(_ctx, _cache, $props, $setup, $data, $options) {
1760
+ const _hoisted_1$13 = ["aria-label"];
1761
+ function _sfc_render$23(_ctx, _cache, $props, $setup, $data, $options) {
1743
1762
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
1744
1763
  class: (0, vue.normalizeClass)(["vue-flow__panel", $setup.positionClasses]),
1745
1764
  "aria-label": $props.label ?? void 0,
1746
1765
  style: (0, vue.normalizeStyle)({ pointerEvents: $setup.userSelectionActive ? "none" : "all" })
1747
- }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 14, _hoisted_1$12);
1766
+ }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 14, _hoisted_1$13);
1748
1767
  }
1749
- var Panel_default = /* @__PURE__ */ export_helper_default(_sfc_main$22, [["render", _sfc_render$22], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Panel/Panel.vue"]]);
1768
+ var Panel_default = /* @__PURE__ */ export_helper_default(_sfc_main$23, [["render", _sfc_render$23], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Panel/Panel.vue"]]);
1750
1769
  //#endregion
1751
1770
  //#region src/components/Controls/icons.ts
1752
1771
  function icon(viewBox, d) {
@@ -1763,7 +1782,7 @@ const Lock = icon("0 0 25 32", "M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 1
1763
1782
  const Unlock = icon("0 0 25 32", "M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z");
1764
1783
  //#endregion
1765
1784
  //#region src/components/Controls/Controls.vue
1766
- const _sfc_main$21 = /* @__PURE__ */ (0, vue.defineComponent)({
1785
+ const _sfc_main$22 = /* @__PURE__ */ (0, vue.defineComponent)({
1767
1786
  name: "Controls",
1768
1787
  compatConfig: { MODE: 3 },
1769
1788
  props: {
@@ -1873,7 +1892,7 @@ const _sfc_main$21 = /* @__PURE__ */ (0, vue.defineComponent)({
1873
1892
  return __returned__;
1874
1893
  }
1875
1894
  });
1876
- function _sfc_render$21(_ctx, _cache, $props, $setup, $data, $options) {
1895
+ function _sfc_render$22(_ctx, _cache, $props, $setup, $data, $options) {
1877
1896
  return (0, vue.openBlock)(), (0, vue.createBlock)($setup["Panel"], {
1878
1897
  class: "vue-flow__controls",
1879
1898
  position: $props.position,
@@ -1920,10 +1939,10 @@ function _sfc_render$21(_ctx, _cache, $props, $setup, $data, $options) {
1920
1939
  _: 3
1921
1940
  }, 8, ["position", "label"]);
1922
1941
  }
1923
- var Controls_default = /* @__PURE__ */ export_helper_default(_sfc_main$21, [["render", _sfc_render$21], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Controls/Controls.vue"]]);
1942
+ var Controls_default = /* @__PURE__ */ export_helper_default(_sfc_main$22, [["render", _sfc_render$22], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Controls/Controls.vue"]]);
1924
1943
  //#endregion
1925
1944
  //#region src/components/Edges/EdgeText.vue
1926
- const _sfc_main$20 = /* @__PURE__ */ (0, vue.defineComponent)({
1945
+ const _sfc_main$21 = /* @__PURE__ */ (0, vue.defineComponent)({
1927
1946
  name: "EdgeText",
1928
1947
  compatConfig: { MODE: 3 },
1929
1948
  props: {
@@ -2003,7 +2022,7 @@ const _sfc_main$20 = /* @__PURE__ */ (0, vue.defineComponent)({
2003
2022
  return __returned__;
2004
2023
  }
2005
2024
  });
2006
- const _hoisted_1$11 = ["transform", "visibility"];
2025
+ const _hoisted_1$12 = ["transform", "visibility"];
2007
2026
  const _hoisted_2$3 = [
2008
2027
  "width",
2009
2028
  "height",
@@ -2013,7 +2032,7 @@ const _hoisted_2$3 = [
2013
2032
  "ry"
2014
2033
  ];
2015
2034
  const _hoisted_3$2 = ["y"];
2016
- function _sfc_render$20(_ctx, _cache, $props, $setup, $data, $options) {
2035
+ function _sfc_render$21(_ctx, _cache, $props, $setup, $data, $options) {
2017
2036
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("g", {
2018
2037
  transform: $setup.transform,
2019
2038
  visibility: $setup.box.width ? "visible" : "hidden",
@@ -2034,12 +2053,12 @@ function _sfc_render$20(_ctx, _cache, $props, $setup, $data, $options) {
2034
2053
  y: $setup.box.height / 2,
2035
2054
  dy: "0.3em",
2036
2055
  style: $props.labelStyle
2037
- }), [(0, vue.renderSlot)(_ctx.$slots, "default", {}, () => [typeof $props.label !== "string" ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)($props.label), { key: 0 })) : ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 1 }, [(0, vue.createTextVNode)((0, vue.toDisplayString)($props.label), 1)], 64))])], 16, _hoisted_3$2)], 8, _hoisted_1$11);
2056
+ }), [(0, vue.renderSlot)(_ctx.$slots, "default", {}, () => [typeof $props.label !== "string" ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)($props.label), { key: 0 })) : ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 1 }, [(0, vue.createTextVNode)((0, vue.toDisplayString)($props.label), 1)], 64))])], 16, _hoisted_3$2)], 8, _hoisted_1$12);
2038
2057
  }
2039
- var EdgeText_default = /* @__PURE__ */ export_helper_default(_sfc_main$20, [["render", _sfc_render$20], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Edges/EdgeText.vue"]]);
2058
+ var EdgeText_default = /* @__PURE__ */ export_helper_default(_sfc_main$21, [["render", _sfc_render$21], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Edges/EdgeText.vue"]]);
2040
2059
  //#endregion
2041
2060
  //#region src/components/Edges/BaseEdge.vue
2042
- const _sfc_main$19 = /* @__PURE__ */ (0, vue.defineComponent)({
2061
+ const _sfc_main$20 = /* @__PURE__ */ (0, vue.defineComponent)({
2043
2062
  name: "BaseEdge",
2044
2063
  inheritAttrs: false,
2045
2064
  compatConfig: { MODE: 3 },
@@ -2122,14 +2141,14 @@ const _sfc_main$19 = /* @__PURE__ */ (0, vue.defineComponent)({
2122
2141
  return __returned__;
2123
2142
  }
2124
2143
  });
2125
- const _hoisted_1$10 = [
2144
+ const _hoisted_1$11 = [
2126
2145
  "id",
2127
2146
  "d",
2128
2147
  "marker-end",
2129
2148
  "marker-start"
2130
2149
  ];
2131
2150
  const _hoisted_2$2 = ["d", "stroke-width"];
2132
- function _sfc_render$19(_ctx, _cache, $props, $setup, $data, $options) {
2151
+ function _sfc_render$20(_ctx, _cache, $props, $setup, $data, $options) {
2133
2152
  return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, null, [
2134
2153
  (0, vue.createElementVNode)("path", (0, vue.mergeProps)($setup.attrs, {
2135
2154
  id: $props.id,
@@ -2138,7 +2157,7 @@ function _sfc_render$19(_ctx, _cache, $props, $setup, $data, $options) {
2138
2157
  class: "vue-flow__edge-path",
2139
2158
  "marker-end": $props.markerEnd,
2140
2159
  "marker-start": $props.markerStart
2141
- }), null, 16, _hoisted_1$10),
2160
+ }), null, 16, _hoisted_1$11),
2142
2161
  $props.interactionWidth ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("path", {
2143
2162
  key: 0,
2144
2163
  ref: "interactionEl",
@@ -2171,7 +2190,7 @@ function _sfc_render$19(_ctx, _cache, $props, $setup, $data, $options) {
2171
2190
  ])) : (0, vue.createCommentVNode)("v-if", true)
2172
2191
  ], 64);
2173
2192
  }
2174
- var BaseEdge_default = /* @__PURE__ */ export_helper_default(_sfc_main$19, [["render", _sfc_render$19], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Edges/BaseEdge.vue"]]);
2193
+ var BaseEdge_default = /* @__PURE__ */ export_helper_default(_sfc_main$20, [["render", _sfc_render$20], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Edges/BaseEdge.vue"]]);
2175
2194
  //#endregion
2176
2195
  //#region src/components/Edges/utils.ts
2177
2196
  /**
@@ -2239,7 +2258,7 @@ const BezierEdge = (0, vue.defineComponent)({
2239
2258
  });
2240
2259
  //#endregion
2241
2260
  //#region src/components/Edges/EdgeLabelRenderer.vue
2242
- const _sfc_main$18 = /* @__PURE__ */ (0, vue.defineComponent)({
2261
+ const _sfc_main$19 = /* @__PURE__ */ (0, vue.defineComponent)({
2243
2262
  name: "EdgeLabelRenderer",
2244
2263
  compatConfig: { MODE: 3 },
2245
2264
  setup(__props, { expose: __expose }) {
@@ -2256,17 +2275,17 @@ const _sfc_main$18 = /* @__PURE__ */ (0, vue.defineComponent)({
2256
2275
  return __returned__;
2257
2276
  }
2258
2277
  });
2259
- const _hoisted_1$9 = {
2278
+ const _hoisted_1$10 = {
2260
2279
  height: "0",
2261
2280
  width: "0"
2262
2281
  };
2263
- function _sfc_render$18(_ctx, _cache, $props, $setup, $data, $options) {
2264
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("svg", null, [((0, vue.openBlock)(), (0, vue.createElementBlock)("foreignObject", _hoisted_1$9, [((0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, {
2282
+ function _sfc_render$19(_ctx, _cache, $props, $setup, $data, $options) {
2283
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("svg", null, [((0, vue.openBlock)(), (0, vue.createElementBlock)("foreignObject", _hoisted_1$10, [((0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, {
2265
2284
  to: $setup.teleportTarget,
2266
2285
  disabled: !$setup.teleportTarget
2267
2286
  }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 8, ["to", "disabled"]))]))]);
2268
2287
  }
2269
- var EdgeLabelRenderer_default = /* @__PURE__ */ export_helper_default(_sfc_main$18, [["render", _sfc_render$18], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Edges/EdgeLabelRenderer.vue"]]);
2288
+ var EdgeLabelRenderer_default = /* @__PURE__ */ export_helper_default(_sfc_main$19, [["render", _sfc_render$19], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Edges/EdgeLabelRenderer.vue"]]);
2270
2289
  //#endregion
2271
2290
  //#region src/components/Edges/SimpleBezierEdge.ts
2272
2291
  function getControl({ pos, x1, y1, x2, y2 }) {
@@ -2475,7 +2494,7 @@ const StraightEdge = (0, vue.defineComponent)({
2475
2494
  });
2476
2495
  //#endregion
2477
2496
  //#region src/components/Handle/Handle.vue
2478
- const _sfc_main$17 = /* @__PURE__ */ (0, vue.defineComponent)({
2497
+ const _sfc_main$18 = /* @__PURE__ */ (0, vue.defineComponent)({
2479
2498
  name: "Handle",
2480
2499
  compatConfig: { MODE: 3 },
2481
2500
  props: {
@@ -2647,8 +2666,8 @@ const _sfc_main$17 = /* @__PURE__ */ (0, vue.defineComponent)({
2647
2666
  return __returned__;
2648
2667
  }
2649
2668
  });
2650
- const _hoisted_1$8 = ["aria-label"];
2651
- function _sfc_render$17(_ctx, _cache, $props, $setup, $data, $options) {
2669
+ const _hoisted_1$9 = ["aria-label"];
2670
+ function _sfc_render$18(_ctx, _cache, $props, $setup, $data, $options) {
2652
2671
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", (0, vue.mergeProps)({ ref: "handle" }, $setup.handleDataIds, {
2653
2672
  "aria-label": $setup.store.ariaLabelConfig["handle.ariaLabel"],
2654
2673
  class: ["vue-flow__handle", [
@@ -2662,9 +2681,84 @@ function _sfc_render$17(_ctx, _cache, $props, $setup, $data, $options) {
2662
2681
  onMousedown: $setup.onPointerDown,
2663
2682
  onTouchstartPassive: $setup.onPointerDown,
2664
2683
  onClick: $setup.onClick
2665
- }), [(0, vue.renderSlot)(_ctx.$slots, "default", { id: $props.id })], 16, _hoisted_1$8);
2684
+ }), [(0, vue.renderSlot)(_ctx.$slots, "default", { id: $props.id })], 16, _hoisted_1$9);
2666
2685
  }
2667
- var Handle_default = /* @__PURE__ */ export_helper_default(_sfc_main$17, [["render", _sfc_render$17], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Handle/Handle.vue"]]);
2686
+ var Handle_default = /* @__PURE__ */ export_helper_default(_sfc_main$18, [["render", _sfc_render$18], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/Handle/Handle.vue"]]);
2687
+ //#endregion
2688
+ //#region src/components/EdgeToolbar/EdgeToolbar.vue
2689
+ const _sfc_main$17 = /* @__PURE__ */ (0, vue.defineComponent)({
2690
+ name: "EdgeToolbar",
2691
+ compatConfig: { MODE: 3 },
2692
+ inheritAttrs: false,
2693
+ props: {
2694
+ edgeId: {
2695
+ type: String,
2696
+ required: true
2697
+ },
2698
+ x: {
2699
+ type: Number,
2700
+ required: true
2701
+ },
2702
+ y: {
2703
+ type: Number,
2704
+ required: true
2705
+ },
2706
+ isVisible: {
2707
+ type: Boolean,
2708
+ required: false,
2709
+ default: void 0
2710
+ },
2711
+ alignX: {
2712
+ type: String,
2713
+ required: false,
2714
+ default: "center"
2715
+ },
2716
+ alignY: {
2717
+ type: String,
2718
+ required: false,
2719
+ default: "center"
2720
+ }
2721
+ },
2722
+ setup(__props, { expose: __expose }) {
2723
+ __expose();
2724
+ const props = __props;
2725
+ const { viewport } = useVueFlow();
2726
+ const { edgeLookup } = useStore();
2727
+ const edge = (0, vue.computed)(() => edgeLookup.get(props.edgeId));
2728
+ const __returned__ = {
2729
+ props,
2730
+ viewport,
2731
+ edgeLookup,
2732
+ edge,
2733
+ isActive: (0, vue.computed)(() => typeof props.isVisible === "boolean" ? props.isVisible : edge.value?.selected),
2734
+ wrapperStyle: (0, vue.computed)(() => ({
2735
+ position: "absolute",
2736
+ transform: (0, _xyflow_system.getEdgeToolbarTransform)(props.x, props.y, viewport.value.zoom, props.alignX, props.alignY),
2737
+ zIndex: (edge.value?.zIndex ?? 0) + 1,
2738
+ pointerEvents: "all",
2739
+ transformOrigin: "0 0"
2740
+ })),
2741
+ EdgeLabelRenderer: EdgeLabelRenderer_default
2742
+ };
2743
+ Object.defineProperty(__returned__, "__isScriptSetup", {
2744
+ enumerable: false,
2745
+ value: true
2746
+ });
2747
+ return __returned__;
2748
+ }
2749
+ });
2750
+ const _hoisted_1$8 = ["data-id"];
2751
+ function _sfc_render$17(_ctx, _cache, $props, $setup, $data, $options) {
2752
+ return $setup.isActive ? ((0, vue.openBlock)(), (0, vue.createBlock)($setup["EdgeLabelRenderer"], { key: 0 }, {
2753
+ default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("div", (0, vue.mergeProps)(_ctx.$attrs, {
2754
+ style: $setup.wrapperStyle,
2755
+ "data-id": $setup.edge?.id ?? "",
2756
+ class: "vue-flow__edge-toolbar"
2757
+ }), [(0, vue.renderSlot)(_ctx.$slots, "default")], 16, _hoisted_1$8)]),
2758
+ _: 3
2759
+ })) : (0, vue.createCommentVNode)("v-if", true);
2760
+ }
2761
+ var EdgeToolbar_default = /* @__PURE__ */ export_helper_default(_sfc_main$17, [["render", _sfc_render$17], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/components/EdgeToolbar/EdgeToolbar.vue"]]);
2668
2762
  //#endregion
2669
2763
  //#region src/components/MiniMap/types.ts
2670
2764
  const Slots = Symbol("MiniMapSlots");
@@ -3307,14 +3401,16 @@ const _sfc_main$14 = /* @__PURE__ */ (0, vue.defineComponent)({
3307
3401
  const { nodeLookup, parentLookup } = useStore();
3308
3402
  const { transform, nodeOrigin, snapGrid, snapToGrid, vueFlowRef, noDragClassName } = storeToRefs(useStore());
3309
3403
  const resizeControlRef = (0, vue.shallowRef)();
3404
+ const contextNodeId = (0, vue.inject)(NodeId, null);
3405
+ const nodeId = (0, vue.toRef)(() => typeof props.nodeId === "string" ? props.nodeId : contextNodeId ?? void 0);
3310
3406
  const controlPosition = (0, vue.toRef)(() => props.position ?? DefaultPositions[props.variant]);
3311
3407
  const positionClassNames = (0, vue.computed)(() => controlPosition.value.split("-"));
3312
3408
  const controlStyle = (0, vue.toRef)(() => props.color ? { [StylingProperty[props.variant]]: props.color } : {});
3313
3409
  (0, vue.watchEffect)((onCleanup) => {
3314
- if (!resizeControlRef.value || !props.nodeId) return;
3410
+ if (!resizeControlRef.value || !nodeId.value) return;
3315
3411
  const resizerInstance = (0, _xyflow_system.XYResizer)({
3316
3412
  domNode: resizeControlRef.value,
3317
- nodeId: props.nodeId,
3413
+ nodeId: nodeId.value,
3318
3414
  getStoreItems: () => ({
3319
3415
  nodeLookup,
3320
3416
  transform: transform.value,
@@ -3325,7 +3421,7 @@ const _sfc_main$14 = /* @__PURE__ */ (0, vue.defineComponent)({
3325
3421
  }),
3326
3422
  onChange: (changes, childChanges) => {
3327
3423
  const nodeChanges = [];
3328
- const node = nodeLookup.get(props.nodeId);
3424
+ const node = nodeLookup.get(nodeId.value);
3329
3425
  let nextX = changes.x;
3330
3426
  let nextY = changes.y;
3331
3427
  if (node?.expandParent && node.parentId) {
@@ -3357,14 +3453,14 @@ const _sfc_main$14 = /* @__PURE__ */ (0, vue.defineComponent)({
3357
3453
  y: nextY ?? node?.position.y ?? 0
3358
3454
  };
3359
3455
  nodeChanges.push({
3360
- id: props.nodeId,
3456
+ id: nodeId.value,
3361
3457
  type: "position",
3362
3458
  position,
3363
3459
  positionAbsolute: position
3364
3460
  });
3365
3461
  }
3366
3462
  if (typeof changes.width !== "undefined" || typeof changes.height !== "undefined") nodeChanges.push({
3367
- id: props.nodeId,
3463
+ id: nodeId.value,
3368
3464
  type: "dimensions",
3369
3465
  setAttributes: true,
3370
3466
  resizing: true,
@@ -3383,7 +3479,7 @@ const _sfc_main$14 = /* @__PURE__ */ (0, vue.defineComponent)({
3383
3479
  },
3384
3480
  onEnd: ({ width, height }) => {
3385
3481
  triggerEmits.nodesChange([{
3386
- id: props.nodeId,
3482
+ id: nodeId.value,
3387
3483
  type: "dimensions",
3388
3484
  resizing: false,
3389
3485
  dimensions: {
@@ -3434,6 +3530,8 @@ const _sfc_main$14 = /* @__PURE__ */ (0, vue.defineComponent)({
3434
3530
  vueFlowRef,
3435
3531
  noDragClassName,
3436
3532
  resizeControlRef,
3533
+ contextNodeId,
3534
+ nodeId,
3437
3535
  controlPosition,
3438
3536
  positionClassNames,
3439
3537
  controlStyle,
@@ -4277,8 +4375,11 @@ function useActions(state, nodeLookup, parentLookup, edgeLookup) {
4277
4375
  */
4278
4376
  function commitEdges(next) {
4279
4377
  const rawEdgeLookup = (0, vue.toRaw)(edgeLookup);
4378
+ const seenEdgeIds = /* @__PURE__ */ new Set();
4280
4379
  for (let i = 0; i < next.length; i++) {
4281
4380
  const edge = next[i] = (0, vue.markRaw)((0, vue.toRaw)(next[i]));
4381
+ if (seenEdgeIds.has(edge.id)) state.hooks.error.trigger(new VueFlowError("EDGE_DUPLICATE_ID", edge.id));
4382
+ else seenEdgeIds.add(edge.id);
4282
4383
  if (rawEdgeLookup.get(edge.id) !== edge) edgeLookup.set(edge.id, edge);
4283
4384
  }
4284
4385
  if (rawEdgeLookup.size !== next.length) {
@@ -4962,17 +5063,14 @@ function useGetters(state, nodeLookup) {
4962
5063
  * @internal
4963
5064
  */
4964
5065
  function createVueFlowStore(id, preloadedState, onDestroy, signals) {
4965
- const nodesSignal = signals?.nodes ?? (0, vue.shallowRef)([]);
4966
- const edgesSignal = signals?.edges ?? (0, vue.shallowRef)([]);
4967
- let lastWriteNodes;
4968
- let lastWriteEdges;
5066
+ const nodesSignal = (0, vue.shallowRef)(signals?.nodes?.value ?? []);
5067
+ const edgesSignal = (0, vue.shallowRef)(signals?.edges?.value ?? []);
4969
5068
  const emptyNodes = [];
4970
5069
  const emptyEdges = [];
4971
5070
  const state = useState();
4972
5071
  Object.defineProperty(state, "nodes", {
4973
5072
  get: () => nodesSignal.value ?? emptyNodes,
4974
5073
  set: (value) => {
4975
- lastWriteNodes = (0, vue.toRaw)(value);
4976
5074
  nodesSignal.value = value;
4977
5075
  },
4978
5076
  enumerable: true,
@@ -4981,7 +5079,6 @@ function createVueFlowStore(id, preloadedState, onDestroy, signals) {
4981
5079
  Object.defineProperty(state, "edges", {
4982
5080
  get: () => edgesSignal.value ?? emptyEdges,
4983
5081
  set: (value) => {
4984
- lastWriteEdges = (0, vue.toRaw)(value);
4985
5082
  edgesSignal.value = value;
4986
5083
  },
4987
5084
  enumerable: true,
@@ -5004,14 +5101,6 @@ function createVueFlowStore(id, preloadedState, onDestroy, signals) {
5004
5101
  ...reactiveState,
5005
5102
  ...preloadedState
5006
5103
  });
5007
- if (signals?.nodes) (0, vue.watch)(nodesSignal, (next) => {
5008
- const nextRaw = next && (0, vue.toRaw)(next);
5009
- if (nextRaw && nextRaw !== lastWriteNodes) actions.setNodes(nextRaw);
5010
- });
5011
- if (signals?.edges) (0, vue.watch)(edgesSignal, (next) => {
5012
- const nextRaw = next && (0, vue.toRaw)(next);
5013
- if (nextRaw && nextRaw !== lastWriteEdges) actions.setEdges(nextRaw);
5014
- });
5015
5104
  return {
5016
5105
  instance: {
5017
5106
  ...hooksOn,
@@ -5162,7 +5251,7 @@ function useViewportSync(model, state = useStore()) {
5162
5251
  };
5163
5252
  if (sameViewport(viewport, model.value)) return;
5164
5253
  model.value = viewport;
5165
- });
5254
+ }, { flush: "sync" });
5166
5255
  }
5167
5256
  //#endregion
5168
5257
  //#region src/components/ConnectionLine/index.ts
@@ -5195,13 +5284,13 @@ const ConnectionLine = (0, vue.defineComponent)({
5195
5284
  }
5196
5285
  const fromHandle = (startHandleId ? handleBounds.find((d) => d.id === startHandleId) : handleBounds[0]) ?? null;
5197
5286
  const fromPosition = fromHandle?.position ?? _xyflow_system.Position.Top;
5198
- const { x: fromX, y: fromY } = (0, _xyflow_system.getHandlePosition)(fromNode.value, fromHandle, fromPosition);
5287
+ const { x: fromX, y: fromY } = (0, _xyflow_system.getHandlePosition)(fromNode.value, fromHandle, fromPosition, true);
5199
5288
  let toHandle = null;
5200
5289
  if (toNode.value) if (connectionMode.value === _xyflow_system.ConnectionMode.Strict) toHandle = toNode.value.internals.handleBounds?.[handleType === "source" ? "target" : "source"]?.find((d) => d.id === connectionEndHandle.value?.id) || null;
5201
5290
  else toHandle = [...toNode.value.internals.handleBounds?.source ?? [], ...toNode.value.internals.handleBounds?.target ?? []].find((d) => d.id === connectionEndHandle.value?.id) || null;
5202
5291
  const toPosition = connectionEndHandle.value?.position ?? (fromPosition ? _xyflow_system.oppositePosition[fromPosition] : null);
5203
5292
  if (!fromPosition || !toPosition) return null;
5204
- const { x: toX, y: toY } = toHandle && toNode.value ? (0, _xyflow_system.getHandlePosition)(toNode.value, toHandle, toPosition) : pointer.value;
5293
+ const { x: toX, y: toY } = toHandle && toNode.value ? (0, _xyflow_system.getHandlePosition)(toNode.value, toHandle, toPosition, true) : pointer.value;
5205
5294
  const type = connectionLineOptions.value.type ?? _xyflow_system.ConnectionLineType.Bezier;
5206
5295
  let dAttr = "";
5207
5296
  const pathParams = {
@@ -5942,6 +6031,8 @@ const NodeWrapper = (0, vue.defineComponent)({
5942
6031
  const getStyle = (0, vue.computed)(() => {
5943
6032
  const node = nodeRef.value;
5944
6033
  const styles = { ...node?.style };
6034
+ if (typeof styles.width === "number") styles.width = `${styles.width}px`;
6035
+ if (typeof styles.height === "number") styles.height = `${styles.height}px`;
5945
6036
  const isMeasured = !!node?.internals.handleBounds;
5946
6037
  const width = node?.width ?? (isMeasured ? void 0 : node?.initialWidth);
5947
6038
  const height = node?.height ?? (isMeasured ? void 0 : node?.initialHeight);
@@ -7310,7 +7401,7 @@ const _sfc_main$1 = /* @__PURE__ */ (0, vue.defineComponent)({
7310
7401
  }, props, {
7311
7402
  instance,
7312
7403
  state
7313
- }, ownsStore);
7404
+ });
7314
7405
  useHooks(emit, state.hooks);
7315
7406
  useOnInitHandler(instance);
7316
7407
  useSelectionChange(instance);
@@ -7383,6 +7474,120 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
7383
7474
  }
7384
7475
  var VueFlowProvider_default = /* @__PURE__ */ export_helper_default(_sfc_main, [["render", _sfc_render], ["__file", "/Users/moritz/xyflow/xyflow/packages/vue/src/container/VueFlowProvider/VueFlowProvider.vue"]]);
7385
7476
  //#endregion
7477
+ //#region src/utils/prop-of.ts
7478
+ function propOf(required = false) {
7479
+ return {
7480
+ type: null,
7481
+ required
7482
+ };
7483
+ }
7484
+ //#endregion
7485
+ //#region src/props-objects.gen.ts
7486
+ function nodeProps() {
7487
+ return {
7488
+ data: propOf(true),
7489
+ deletable: propOf(true),
7490
+ dragHandle: propOf(),
7491
+ draggable: propOf(true),
7492
+ dragging: propOf(true),
7493
+ height: propOf(),
7494
+ id: propOf(true),
7495
+ isConnectable: propOf(true),
7496
+ parentId: propOf(),
7497
+ positionAbsoluteX: propOf(true),
7498
+ positionAbsoluteY: propOf(true),
7499
+ selectable: propOf(true),
7500
+ selected: propOf(true),
7501
+ sourcePosition: propOf(),
7502
+ targetPosition: propOf(),
7503
+ type: propOf(true),
7504
+ width: propOf(),
7505
+ zIndex: propOf(true)
7506
+ };
7507
+ }
7508
+ function edgeProps() {
7509
+ return {
7510
+ animated: propOf(),
7511
+ curvature: propOf(),
7512
+ data: propOf(),
7513
+ deletable: propOf(),
7514
+ id: propOf(true),
7515
+ interactionWidth: propOf(),
7516
+ label: propOf(),
7517
+ labelBgBorderRadius: propOf(),
7518
+ labelBgPadding: propOf(),
7519
+ labelBgStyle: propOf(),
7520
+ labelShowBg: propOf(),
7521
+ labelStyle: propOf(),
7522
+ markerEnd: propOf(),
7523
+ markerStart: propOf(),
7524
+ reconnectable: propOf(),
7525
+ selectable: propOf(),
7526
+ selected: propOf(),
7527
+ source: propOf(true),
7528
+ sourceHandleId: propOf(),
7529
+ sourcePosition: propOf(true),
7530
+ sourceX: propOf(true),
7531
+ sourceY: propOf(true),
7532
+ style: propOf(),
7533
+ target: propOf(true),
7534
+ targetHandleId: propOf(),
7535
+ targetPosition: propOf(true),
7536
+ targetX: propOf(true),
7537
+ targetY: propOf(true),
7538
+ type: propOf()
7539
+ };
7540
+ }
7541
+ function connectionLineProps() {
7542
+ return {
7543
+ connectionStatus: propOf(true),
7544
+ fromHandle: propOf(true),
7545
+ fromNode: propOf(true),
7546
+ fromPosition: propOf(true),
7547
+ fromX: propOf(true),
7548
+ fromY: propOf(true),
7549
+ markerEnd: propOf(),
7550
+ markerStart: propOf(),
7551
+ pointer: propOf(true),
7552
+ toHandle: propOf(true),
7553
+ toNode: propOf(true),
7554
+ toPosition: propOf(true),
7555
+ toX: propOf(true),
7556
+ toY: propOf(true)
7557
+ };
7558
+ }
7559
+ //#endregion
7560
+ //#region src/utils/edges.ts
7561
+ const defaultOnError = (0, _xyflow_system.createDevWarn)("Vue Flow", "https://vueflow.dev/");
7562
+ /**
7563
+ * Adds a `Connection` (or a full `Edge`) to an edges array and returns a new array — generating the
7564
+ * edge id and skipping the add when an equivalent connection already exists. The pure helper to use
7565
+ * in an `@connect` handler against a `v-model:edges` array, e.g.
7566
+ * `edges.value = addEdge(connection, edges.value)`, with no store/instance access.
7567
+ *
7568
+ * Mirrors xyflow/react's + xyflow/svelte's `addEdge`.
7569
+ */
7570
+ function addEdge(edgeParams, edges, options = {}) {
7571
+ return (0, _xyflow_system.addEdge)(edgeParams, edges, {
7572
+ ...options,
7573
+ onError: options.onError ?? defaultOnError
7574
+ });
7575
+ }
7576
+ /**
7577
+ * Reconnects an existing edge to a new `Connection`, returning a new edges array. The pure,
7578
+ * controlled counterpart to the store action `useVueFlow().reconnectEdge` — use it in an
7579
+ * `@reconnect` handler against a `v-model:edges` array, e.g.
7580
+ * `edges.value = reconnectEdge(oldEdge, newConnection, edges.value)`.
7581
+ *
7582
+ * Mirrors xyflow/react's `reconnectEdge`.
7583
+ */
7584
+ function reconnectEdge(oldEdge, newConnection, edges, options = { shouldReplaceId: true }) {
7585
+ return (0, _xyflow_system.reconnectEdge)(oldEdge, newConnection, edges, {
7586
+ ...options,
7587
+ onError: options.onError ?? defaultOnError
7588
+ });
7589
+ }
7590
+ //#endregion
7386
7591
  exports.Background = Background_default;
7387
7592
  exports.BaseEdge = BaseEdge_default;
7388
7593
  exports.BezierEdge = BezierEdge;
@@ -7402,6 +7607,7 @@ exports.ControlButton = ControlButton_default;
7402
7607
  exports.Controls = Controls_default;
7403
7608
  exports.EdgeLabelRenderer = EdgeLabelRenderer_default;
7404
7609
  exports.EdgeText = EdgeText_default;
7610
+ exports.EdgeToolbar = EdgeToolbar_default;
7405
7611
  exports.ErrorCode = ErrorCode;
7406
7612
  exports.Handle = Handle_default;
7407
7613
  exports.MarkerType = MarkerType;
@@ -7445,6 +7651,7 @@ exports.VueFlow = VueFlow_default;
7445
7651
  exports.VueFlowError = VueFlowError;
7446
7652
  exports.VueFlowInjection = VueFlow;
7447
7653
  exports.VueFlowProvider = VueFlowProvider_default;
7654
+ exports.addEdge = addEdge;
7448
7655
  exports.applyChanges = applyChanges;
7449
7656
  exports.applyEdgeChanges = applyEdgeChanges;
7450
7657
  exports.applyNodeChanges = applyNodeChanges;
@@ -7455,8 +7662,10 @@ Object.defineProperty(exports, "clamp", {
7455
7662
  }
7456
7663
  });
7457
7664
  exports.connectionExists = connectionExists;
7665
+ exports.connectionLineProps = connectionLineProps;
7458
7666
  exports.defaultEdgeTypes = defaultEdgeTypes;
7459
7667
  exports.defaultNodeTypes = defaultNodeTypes;
7668
+ exports.edgeProps = edgeProps;
7460
7669
  Object.defineProperty(exports, "getBezierEdgeCenter", {
7461
7670
  enumerable: true,
7462
7671
  get: function() {
@@ -7570,12 +7779,14 @@ Object.defineProperty(exports, "isNodeBase", {
7570
7779
  return _xyflow_system.isNodeBase;
7571
7780
  }
7572
7781
  });
7782
+ exports.nodeProps = nodeProps;
7573
7783
  Object.defineProperty(exports, "pointToRendererPoint", {
7574
7784
  enumerable: true,
7575
7785
  get: function() {
7576
7786
  return _xyflow_system.pointToRendererPoint;
7577
7787
  }
7578
7788
  });
7789
+ exports.reconnectEdge = reconnectEdge;
7579
7790
  Object.defineProperty(exports, "rendererPointToPoint", {
7580
7791
  enumerable: true,
7581
7792
  get: function() {