@dschz/solid-flow 0.1.4 → 0.2.1

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.
@@ -1232,7 +1232,7 @@ var OutputNode = (props) => {
1232
1232
 
1233
1233
  // src/data/defaults.ts
1234
1234
  import {
1235
- devWarn,
1235
+ createDevWarn,
1236
1236
  infiniteExtent
1237
1237
  } from "@xyflow/system";
1238
1238
  var getDefaultFlowStateProps = () => ({
@@ -1258,6 +1258,7 @@ var getDefaultFlowStateProps = () => ({
1258
1258
  autoPanOnNodeDrag: true,
1259
1259
  autoPanOnConnect: true,
1260
1260
  autoPanOnNodeFocus: true,
1261
+ autoPanOnSelection: true,
1261
1262
  autoPanSpeed: 15,
1262
1263
  elevateEdgesOnSelect: true,
1263
1264
  nodesDraggable: true,
@@ -1267,13 +1268,14 @@ var getDefaultFlowStateProps = () => ({
1267
1268
  elementsSelectable: true,
1268
1269
  selectNodesOnDrag: true,
1269
1270
  elevateNodesOnSelect: true,
1271
+ zIndexMode: "basic",
1270
1272
  onlyRenderVisibleElements: false,
1271
1273
  disableKeyboardA11y: false,
1272
1274
  defaultMarkerColor: "#b1b1b7",
1273
1275
  ariaLiveMessage: "",
1274
1276
  style: {},
1275
- isValidConnection: () => true,
1276
- onFlowError: devWarn
1277
+ isValidConnection: (() => true),
1278
+ onFlowError: createDevWarn("Solid Flow", "https://solidflow.dev/")
1277
1279
  });
1278
1280
 
1279
1281
  // src/data/xyflow.ts
@@ -1290,12 +1292,18 @@ import {
1290
1292
  isNumeric,
1291
1293
  nodeToRect
1292
1294
  } from "@xyflow/system";
1295
+ var SELECTED_NODE_Z = 1e3;
1296
+ var ROOT_PARENT_Z_INCREMENT = 10;
1293
1297
  var defaultOptions = {
1294
1298
  nodeOrigin: [0, 0],
1295
1299
  nodeExtent: infiniteExtent2,
1296
1300
  elevateNodesOnSelect: true,
1297
- defaults: {}
1301
+ defaults: {},
1302
+ zIndexMode: "basic"
1298
1303
  };
1304
+ function isManualZIndexMode(zIndexMode) {
1305
+ return zIndexMode === "manual";
1306
+ }
1299
1307
  var adoptUserNodesDefaultOptions = {
1300
1308
  ...defaultOptions,
1301
1309
  checkEquality: true
@@ -1312,8 +1320,9 @@ function mergeObjects(base, incoming) {
1312
1320
  function adoptUserNodes(nodes, nodeLookup, parentLookup, options) {
1313
1321
  const _options = mergeObjects(adoptUserNodesDefaultOptions, options);
1314
1322
  let nodesInitialized = nodes.length > 0;
1323
+ const rootParentIndex = { i: 0 };
1315
1324
  const tmpLookup = new Map(nodeLookup);
1316
- const selectedNodeZ = _options?.elevateNodesOnSelect ? 1e3 : 0;
1325
+ const selectedNodeZ = _options?.elevateNodesOnSelect && !isManualZIndexMode(_options.zIndexMode) ? SELECTED_NODE_Z : 0;
1317
1326
  nodeLookup.clear();
1318
1327
  parentLookup.clear();
1319
1328
  for (const userNode of nodes) {
@@ -1339,7 +1348,7 @@ function adoptUserNodes(nodes, nodeLookup, parentLookup, options) {
1339
1348
  positionAbsolute: clampedPosition,
1340
1349
  // if user re-initializes the node or removes `measured` for whatever reason, we reset the handleBounds so that the node gets re-measured
1341
1350
  handleBounds: !userNode.measured ? void 0 : internalNode?.internals.handleBounds,
1342
- z: calculateZ(userNode, selectedNodeZ),
1351
+ z: calculateZ(userNode, selectedNodeZ, _options.zIndexMode),
1343
1352
  userNode
1344
1353
  }
1345
1354
  };
@@ -1349,7 +1358,7 @@ function adoptUserNodes(nodes, nodeLookup, parentLookup, options) {
1349
1358
  nodesInitialized = false;
1350
1359
  }
1351
1360
  if (userNode.parentId) {
1352
- updateChildNode(internalNode, nodeLookup, parentLookup, options);
1361
+ updateChildNode(internalNode, nodeLookup, parentLookup, options, rootParentIndex);
1353
1362
  }
1354
1363
  }
1355
1364
  return nodesInitialized;
@@ -1365,16 +1374,33 @@ function updateParentLookup(node, parentLookup) {
1365
1374
  parentLookup.set(node.parentId, /* @__PURE__ */ new Map([[node.id, node]]));
1366
1375
  }
1367
1376
  }
1368
- function updateChildNode(node, nodeLookup, parentLookup, options) {
1369
- const { elevateNodesOnSelect, nodeOrigin, nodeExtent } = mergeObjects(defaultOptions, options);
1377
+ function updateChildNode(node, nodeLookup, parentLookup, options, rootParentIndex) {
1378
+ const { elevateNodesOnSelect, nodeOrigin, nodeExtent, zIndexMode } = mergeObjects(
1379
+ defaultOptions,
1380
+ options
1381
+ );
1370
1382
  const parentId = node.parentId;
1371
1383
  const parentNode = nodeLookup.get(parentId);
1372
1384
  if (!parentNode) {
1373
1385
  return;
1374
1386
  }
1375
1387
  updateParentLookup(node, parentLookup);
1376
- const selectedNodeZ = elevateNodesOnSelect ? 1e3 : 0;
1377
- const { x, y, z } = calculateChildXYZ(node, parentNode, nodeOrigin, nodeExtent, selectedNodeZ);
1388
+ if (rootParentIndex && !parentNode.parentId && parentNode.internals.rootParentIndex === void 0 && zIndexMode === "auto") {
1389
+ parentNode.internals.rootParentIndex = ++rootParentIndex.i;
1390
+ parentNode.internals.z = parentNode.internals.z + rootParentIndex.i * ROOT_PARENT_Z_INCREMENT;
1391
+ }
1392
+ if (rootParentIndex && parentNode.internals.rootParentIndex !== void 0) {
1393
+ rootParentIndex.i = parentNode.internals.rootParentIndex;
1394
+ }
1395
+ const selectedNodeZ = elevateNodesOnSelect && !isManualZIndexMode(zIndexMode) ? SELECTED_NODE_Z : 0;
1396
+ const { x, y, z } = calculateChildXYZ(
1397
+ node,
1398
+ parentNode,
1399
+ nodeOrigin,
1400
+ nodeExtent,
1401
+ selectedNodeZ,
1402
+ zIndexMode
1403
+ );
1378
1404
  const { positionAbsolute } = node.internals;
1379
1405
  const positionChanged = x !== positionAbsolute.x || y !== positionAbsolute.y;
1380
1406
  if (positionChanged || z !== node.internals.z) {
@@ -1388,10 +1414,14 @@ function updateChildNode(node, nodeLookup, parentLookup, options) {
1388
1414
  });
1389
1415
  }
1390
1416
  }
1391
- function calculateZ(node, selectedNodeZ) {
1392
- return (isNumeric(node.zIndex) ? node.zIndex : 0) + (node.selected ? selectedNodeZ : 0);
1417
+ function calculateZ(node, selectedNodeZ, zIndexMode) {
1418
+ const zIndex = isNumeric(node.zIndex) ? node.zIndex : 0;
1419
+ if (isManualZIndexMode(zIndexMode)) {
1420
+ return zIndex;
1421
+ }
1422
+ return zIndex + (node.selected ? selectedNodeZ : 0);
1393
1423
  }
1394
- function calculateChildXYZ(childNode, parentNode, nodeOrigin, nodeExtent, selectedNodeZ) {
1424
+ function calculateChildXYZ(childNode, parentNode, nodeOrigin, nodeExtent, selectedNodeZ, zIndexMode) {
1395
1425
  const { x: parentX, y: parentY } = parentNode.internals.positionAbsolute;
1396
1426
  const childDimensions = getNodeDimensions(childNode);
1397
1427
  const positionWithOrigin = getNodePositionWithOrigin(childNode, nodeOrigin);
@@ -1404,7 +1434,7 @@ function calculateChildXYZ(childNode, parentNode, nodeOrigin, nodeExtent, select
1404
1434
  if (childNode.extent === "parent") {
1405
1435
  absolutePosition = clampPositionToParent(absolutePosition, childDimensions, parentNode);
1406
1436
  }
1407
- const childZ = calculateZ(childNode, selectedNodeZ);
1437
+ const childZ = calculateZ(childNode, selectedNodeZ, zIndexMode);
1408
1438
  const parentZ = parentNode.internals.z ?? 0;
1409
1439
  return {
1410
1440
  x: absolutePosition.x,
@@ -1486,6 +1516,8 @@ var createSolidFlow = (props) => {
1486
1516
  nodeOrigin: _props.nodeOrigin,
1487
1517
  // eslint-disable-next-line solid/reactivity
1488
1518
  elevateNodesOnSelect: _props.elevateNodesOnSelect,
1519
+ // eslint-disable-next-line solid/reactivity
1520
+ zIndexMode: _props.zIndexMode,
1489
1521
  checkEquality: true
1490
1522
  });
1491
1523
  });
@@ -1541,6 +1573,17 @@ var createSolidFlow = (props) => {
1541
1573
  const transform = createMemo5(
1542
1574
  () => [viewportMemo.get().x, viewportMemo.get().y, viewportMemo.get().zoom]
1543
1575
  );
1576
+ const nodesInitialized = createMemo5(() => {
1577
+ const nodes = nodesMemo.get();
1578
+ if (nodes.length === 0) return false;
1579
+ for (const node of nodes) {
1580
+ if (node.hidden) continue;
1581
+ if (node.measured?.width === void 0 || node.measured?.height === void 0) {
1582
+ return false;
1583
+ }
1584
+ }
1585
+ return true;
1586
+ });
1544
1587
  const store = mergeProps8({ width: 0, height: 0 }, config, {
1545
1588
  get _colorMode() {
1546
1589
  return config().colorMode;
@@ -1573,7 +1616,6 @@ var createSolidFlow = (props) => {
1573
1616
  const state = connection();
1574
1617
  return {
1575
1618
  ...state,
1576
- from: state.inProgress ? pointToRendererPoint(state.from, this.transform) : state.from,
1577
1619
  to: state.inProgress ? pointToRendererPoint(state.to, this.transform) : state.to
1578
1620
  };
1579
1621
  },
@@ -1620,10 +1662,10 @@ var createSolidFlow = (props) => {
1620
1662
  return panZoom();
1621
1663
  },
1622
1664
  get selectedNodes() {
1623
- return config().nodes.filter((node) => node.selected);
1665
+ return nodesMemo.get().filter((node) => node.selected);
1624
1666
  },
1625
1667
  get selectedEdges() {
1626
- return config().edges.filter((edge) => edge.selected);
1668
+ return edgesMemo.get().filter((edge) => edge.selected);
1627
1669
  },
1628
1670
  get selectionRect() {
1629
1671
  return selectionRect();
@@ -1640,6 +1682,9 @@ var createSolidFlow = (props) => {
1640
1682
  get viewportInitialized() {
1641
1683
  return panZoom() !== null;
1642
1684
  },
1685
+ get nodesInitialized() {
1686
+ return nodesInitialized();
1687
+ },
1643
1688
  get visibleEdgeIds() {
1644
1689
  return visibleEdgeIds();
1645
1690
  },
@@ -1687,7 +1732,7 @@ var createSolidFlow = (props) => {
1687
1732
  const getEdge = (id) => layoutedEdgesMap.get(id);
1688
1733
  const fitView = async (options) => {
1689
1734
  if (!store.panZoom) return false;
1690
- return fitViewport(
1735
+ const result = await fitViewport(
1691
1736
  {
1692
1737
  nodes: nodeLookup,
1693
1738
  width: store.width,
@@ -1698,6 +1743,7 @@ var createSolidFlow = (props) => {
1698
1743
  },
1699
1744
  options ?? config().fitViewOptions
1700
1745
  );
1746
+ return result;
1701
1747
  };
1702
1748
  const resetStoreValues = () => {
1703
1749
  setDragging(false);
@@ -1718,9 +1764,16 @@ var createSolidFlow = (props) => {
1718
1764
  edgesMemo.set((edges) => systemAddEdge(edgeParams, edges));
1719
1765
  };
1720
1766
  let initialFitViewApplied = false;
1767
+ let initialNodesMeasured = false;
1721
1768
  const applyInitialFitView = (initialFitView) => {
1722
1769
  initialFitViewApplied = !initialFitView;
1723
1770
  };
1771
+ const tryInitialFitView = () => {
1772
+ if (initialFitViewApplied || !initialNodesMeasured) return;
1773
+ if (!untrack(() => store.panZoom && store.width && store.height)) return;
1774
+ initialFitViewApplied = true;
1775
+ void untrack(() => fitView());
1776
+ };
1724
1777
  const updateNodePositions = (nodeDragItems, dragging2 = false) => {
1725
1778
  nodesMemo.set(
1726
1779
  (node) => nodeDragItems.has(node.id),
@@ -1751,7 +1804,8 @@ var createSolidFlow = (props) => {
1751
1804
  if (!updatedInternals) return;
1752
1805
  updateAbsolutePositions(nodeLookup, parentLookup, {
1753
1806
  nodeOrigin: store.nodeOrigin,
1754
- nodeExtent: store.nodeExtent
1807
+ nodeExtent: store.nodeExtent,
1808
+ zIndexMode: store.zIndexMode
1755
1809
  });
1756
1810
  const nodeToChange = changes.reduce(
1757
1811
  (acc, change) => {
@@ -1781,10 +1835,8 @@ var createSolidFlow = (props) => {
1781
1835
  }
1782
1836
  })
1783
1837
  );
1784
- if (!initialFitViewApplied) {
1785
- initialFitViewApplied = true;
1786
- void fitView();
1787
- }
1838
+ initialNodesMeasured = true;
1839
+ tryInitialFitView();
1788
1840
  });
1789
1841
  });
1790
1842
  };
@@ -1955,6 +2007,9 @@ var createSolidFlow = (props) => {
1955
2007
  resetStoreValues();
1956
2008
  unselectNodesAndEdges();
1957
2009
  };
2010
+ createEffect4(() => {
2011
+ if (width() && height() && panZoom()) tryInitialFitView();
2012
+ });
1958
2013
  createEffect4(() => {
1959
2014
  store.panZoom?.syncViewport(store.viewport);
1960
2015
  });
@@ -1974,7 +2029,7 @@ var createSolidFlow = (props) => {
1974
2029
  (userNode) => {
1975
2030
  createComputed(() => {
1976
2031
  const internalNode = untrack(() => nodeLookup.get(userNode.id));
1977
- const selectedNodeZ = store.elevateNodesOnSelect ? 1e3 : 0;
2032
+ const selectedNodeZ = store.elevateNodesOnSelect && store.zIndexMode !== "manual" ? 1e3 : 0;
1978
2033
  const clampedPosition = clampPosition2(
1979
2034
  getNodePositionWithOrigin2(userNode, store.nodeOrigin),
1980
2035
  isCoordinateExtent2(userNode.extent) ? userNode.extent : store.nodeExtent,
@@ -1992,7 +2047,7 @@ var createSolidFlow = (props) => {
1992
2047
  // If there is neither a user-provided nor a previously measured size,
1993
2048
  // reset handleBounds so that the node gets re-measured.
1994
2049
  handleBounds: !userNode.measured && !internalNode?.measured ? void 0 : internalNode?.internals.handleBounds,
1995
- z: calculateZ(userNode, selectedNodeZ),
2050
+ z: calculateZ(userNode, selectedNodeZ, store.zIndexMode),
1996
2051
  userNode
1997
2052
  }
1998
2053
  };
@@ -2002,6 +2057,7 @@ var createSolidFlow = (props) => {
2002
2057
  nodeOrigin: store.nodeOrigin,
2003
2058
  nodeExtent: store.nodeExtent,
2004
2059
  elevateNodesOnSelect: store.elevateNodesOnSelect,
2060
+ zIndexMode: store.zIndexMode,
2005
2061
  checkEquality: true
2006
2062
  });
2007
2063
  }
@@ -2094,7 +2150,8 @@ var createSolidFlow = (props) => {
2094
2150
  zIndex: edge.zIndex ?? store.defaultEdgeOptions.zIndex,
2095
2151
  sourceNode,
2096
2152
  targetNode,
2097
- elevateOnSelect: store.elevateEdgesOnSelect
2153
+ elevateOnSelect: store.elevateEdgesOnSelect,
2154
+ zIndexMode: store.zIndexMode
2098
2155
  }),
2099
2156
  sourceNode,
2100
2157
  targetNode,
@@ -2343,9 +2400,16 @@ var NodeRenderer = (props) => {
2343
2400
  };
2344
2401
 
2345
2402
  // src/components/container/Pane.tsx
2346
- import { getEventPosition, getNodesInside as getNodesInside3, SelectionMode } from "@xyflow/system";
2403
+ import {
2404
+ calcAutoPan,
2405
+ getEventPosition,
2406
+ getNodesInside as getNodesInside3,
2407
+ pointToRendererPoint as pointToRendererPoint2,
2408
+ rendererPointToPoint,
2409
+ SelectionMode
2410
+ } from "@xyflow/system";
2347
2411
  import clsx7 from "clsx";
2348
- import { batch as batch3 } from "solid-js";
2412
+ import { batch as batch3, onCleanup as onCleanup4 } from "solid-js";
2349
2413
  import { produce as produce2 } from "solid-js/store";
2350
2414
  var isSetEqual = (a, b) => {
2351
2415
  if (a.size !== b.size) return false;
@@ -2360,56 +2424,76 @@ var Pane = (props) => {
2360
2424
  const { store, nodeLookup, edgeLookup, connectionLookup, actions } = useInternalSolidFlow();
2361
2425
  let container;
2362
2426
  let containerBounds = null;
2427
+ let connectionEndedOnPane = false;
2363
2428
  let selectionInProgress = false;
2364
2429
  let selectedNodeIds = /* @__PURE__ */ new Set();
2365
2430
  let selectedEdgeIds = /* @__PURE__ */ new Set();
2431
+ let autoPanId = 0;
2432
+ let position = { x: 0, y: 0 };
2433
+ let autoPanStarted = false;
2434
+ const autoPanOnSelection = () => props.autoPanOnSelection ?? true;
2435
+ const paneClickDistance = () => props.paneClickDistance ?? 1;
2366
2436
  const _panOnDrag = () => store.panActivationKeyPressed || props.panOnDrag;
2367
- const isSelecting = () => store.selectionKeyPressed || store.selectionRect || props.selectionOnDrag && _panOnDrag() !== true;
2368
- const hasActiveSelection = () => store.elementsSelectable && (isSelecting() || store.selectionRectMode === "user");
2437
+ const isSelecting = () => store.selectionKeyPressed || !!store.selectionRect || props.selectionOnDrag && _panOnDrag() !== true;
2438
+ const isSelectionEnabled = () => store.elementsSelectable && (isSelecting() || store.selectionRectMode === "user");
2369
2439
  const onClick = (event) => {
2370
2440
  if (event.target !== container) return;
2371
- if (selectionInProgress) {
2441
+ if (selectionInProgress || store.connection.inProgress || connectionEndedOnPane) {
2372
2442
  selectionInProgress = false;
2443
+ connectionEndedOnPane = false;
2373
2444
  return;
2374
2445
  }
2375
2446
  props.onPaneClick?.({ event });
2376
2447
  batch3(() => {
2377
2448
  actions.unselectNodesAndEdges();
2378
2449
  actions.setSelectionRectMode(void 0);
2450
+ actions.setSelectionRect(void 0);
2379
2451
  });
2380
2452
  };
2381
- const onPointerDown = (event) => {
2453
+ const onPointerDownCapture = (event) => {
2454
+ if (event.pointerType === "touch" && _panOnDrag() !== false && !store.selectionKeyPressed) {
2455
+ return;
2456
+ }
2382
2457
  containerBounds = container?.getBoundingClientRect() ?? null;
2383
- if (!store.elementsSelectable || !isSelecting() || event.button !== 0 || event.target !== container || !containerBounds) {
2458
+ if (!containerBounds) return;
2459
+ const eventTargetIsContainer = event.target === container;
2460
+ const isNoKeyEvent = !eventTargetIsContainer && !!event.target.closest(".nokey");
2461
+ const isSelectionActive = props.selectionOnDrag && eventTargetIsContainer || store.selectionKeyPressed;
2462
+ if (isNoKeyEvent || !isSelecting() || !isSelectionActive || event.button !== 0 || !event.isPrimary) {
2384
2463
  return;
2385
2464
  }
2386
2465
  event.target?.setPointerCapture?.(event.pointerId);
2466
+ selectionInProgress = false;
2467
+ autoPanStarted = false;
2387
2468
  const { x, y } = getEventPosition(event, containerBounds);
2388
- batch3(() => {
2389
- actions.unselectNodesAndEdges();
2390
- actions.setSelectionRect({
2391
- width: 0,
2392
- height: 0,
2393
- startX: x,
2394
- startY: y,
2395
- x,
2396
- y
2397
- });
2469
+ const userSelectionFlowOrigin = pointToRendererPoint2({ x, y }, store.transform);
2470
+ actions.setSelectionRect({
2471
+ width: 0,
2472
+ height: 0,
2473
+ startX: userSelectionFlowOrigin.x,
2474
+ startY: userSelectionFlowOrigin.y,
2475
+ x,
2476
+ y
2398
2477
  });
2478
+ if (!eventTargetIsContainer) {
2479
+ event.stopPropagation();
2480
+ event.preventDefault();
2481
+ }
2399
2482
  };
2400
- const onPointerMove = (event) => {
2401
- if (!isSelecting() || !containerBounds || !store.selectionRect) {
2483
+ const commitUserSelectionRect = (mouseX, mouseY) => {
2484
+ const selectionRect = store.selectionRect;
2485
+ if (selectionRect?.startX === void 0 || selectionRect.startY === void 0) {
2402
2486
  return;
2403
2487
  }
2404
- selectionInProgress = true;
2405
- const mousePos = getEventPosition(event, containerBounds);
2406
- const { startX = 0, startY = 0 } = store.selectionRect;
2488
+ const userStartPosition = { x: selectionRect.startX, y: selectionRect.startY };
2489
+ const screenStart = rendererPointToPoint(userStartPosition, store.transform);
2407
2490
  const nextUserSelectRect = {
2408
- ...store.selectionRect,
2409
- x: mousePos.x < startX ? mousePos.x : startX,
2410
- y: mousePos.y < startY ? mousePos.y : startY,
2411
- width: Math.abs(mousePos.x - startX),
2412
- height: Math.abs(mousePos.y - startY)
2491
+ startX: userStartPosition.x,
2492
+ startY: userStartPosition.y,
2493
+ x: mouseX < screenStart.x ? mouseX : screenStart.x,
2494
+ y: mouseY < screenStart.y ? mouseY : screenStart.y,
2495
+ width: Math.abs(mouseX - screenStart.x),
2496
+ height: Math.abs(mouseY - screenStart.y)
2413
2497
  };
2414
2498
  const prevSelectedNodeIds = selectedNodeIds;
2415
2499
  const prevSelectedEdgeIds = selectedEdgeIds;
@@ -2465,22 +2549,87 @@ var Pane = (props) => {
2465
2549
  actions.setSelectionRect(nextUserSelectRect);
2466
2550
  });
2467
2551
  };
2552
+ const autoPan = () => {
2553
+ if (!autoPanOnSelection() || !containerBounds) {
2554
+ return;
2555
+ }
2556
+ const [x = 0, y = 0] = calcAutoPan(position, containerBounds, store.autoPanSpeed);
2557
+ void actions.panBy({ x, y }).then((panned) => {
2558
+ if (!selectionInProgress || !panned) {
2559
+ autoPanId = requestAnimationFrame(autoPan);
2560
+ return;
2561
+ }
2562
+ commitUserSelectionRect(position.x, position.y);
2563
+ autoPanId = requestAnimationFrame(autoPan);
2564
+ });
2565
+ };
2566
+ const cleanupAutoPan = () => {
2567
+ cancelAnimationFrame(autoPanId);
2568
+ autoPanId = 0;
2569
+ autoPanStarted = false;
2570
+ };
2571
+ onCleanup4(() => {
2572
+ cleanupAutoPan();
2573
+ });
2574
+ const onPointerMove = (event) => {
2575
+ if (!isSelecting() || !containerBounds || !store.selectionRect) {
2576
+ return;
2577
+ }
2578
+ const mousePos = getEventPosition(event, containerBounds);
2579
+ position = { x: mousePos.x, y: mousePos.y };
2580
+ const userStartPosition = {
2581
+ x: store.selectionRect.startX ?? 0,
2582
+ y: store.selectionRect.startY ?? 0
2583
+ };
2584
+ const screenStart = rendererPointToPoint(userStartPosition, store.transform);
2585
+ if (!selectionInProgress) {
2586
+ const requiredDistance = store.selectionKeyPressed ? 0 : paneClickDistance();
2587
+ const distance = Math.hypot(mousePos.x - screenStart.x, mousePos.y - screenStart.y);
2588
+ if (distance <= requiredDistance) {
2589
+ return;
2590
+ }
2591
+ actions.unselectNodesAndEdges();
2592
+ props.onSelectionStart?.(event);
2593
+ }
2594
+ selectionInProgress = true;
2595
+ if (!autoPanStarted) {
2596
+ autoPan();
2597
+ autoPanStarted = true;
2598
+ }
2599
+ commitUserSelectionRect(mousePos.x, mousePos.y);
2600
+ };
2468
2601
  const onPointerUp = (event) => {
2602
+ if (!isSelectionEnabled()) {
2603
+ if (event.target === container && store.connection.inProgress) {
2604
+ connectionEndedOnPane = true;
2605
+ }
2606
+ return;
2607
+ }
2469
2608
  if (event.button !== 0) return;
2470
2609
  event.target?.releasePointerCapture?.(event.pointerId);
2471
- if (!isSelecting() && store.selectionRectMode === "user" && event.target === container) {
2610
+ if (!selectionInProgress && event.target === container) {
2472
2611
  onClick(event);
2473
2612
  }
2474
2613
  batch3(() => {
2475
2614
  actions.setSelectionRect(void 0);
2476
- if (selectedNodeIds.size > 0) {
2477
- actions.setSelectionRectMode("nodes");
2615
+ if (selectionInProgress) {
2616
+ actions.setSelectionRectMode(selectedNodeIds.size > 0 ? "nodes" : void 0);
2478
2617
  }
2479
2618
  });
2480
- if (store.selectionKeyPressed) {
2619
+ if (selectionInProgress) {
2620
+ props.onSelectionEnd?.(event);
2621
+ }
2622
+ cleanupAutoPan();
2623
+ };
2624
+ const onPointerCancel = (event) => {
2625
+ event.target?.releasePointerCapture?.(event.pointerId);
2626
+ cleanupAutoPan();
2627
+ };
2628
+ const onClickCapture = (event) => {
2629
+ if (selectionInProgress) {
2630
+ event.stopPropagation();
2481
2631
  selectionInProgress = false;
2482
2632
  }
2483
- props.onSelectionEnd?.(event);
2484
2633
  };
2485
2634
  const onContextMenu = (event) => {
2486
2635
  if (event.target !== container) return;
@@ -2492,16 +2641,31 @@ var Pane = (props) => {
2492
2641
  props.onPaneContextMenu?.({ event });
2493
2642
  };
2494
2643
  return <div
2495
- ref={container}
2644
+ ref={(el) => {
2645
+ container = el;
2646
+ el.addEventListener(
2647
+ "click",
2648
+ (e) => {
2649
+ if (isSelectionEnabled()) onClickCapture(e);
2650
+ },
2651
+ { capture: true }
2652
+ );
2653
+ }}
2496
2654
  class={clsx7("solid-flow__container solid-flow__pane", {
2497
2655
  selection: isSelecting(),
2498
2656
  dragging: store.dragging,
2499
2657
  draggable: props.panOnDrag === true || Array.isArray(props.panOnDrag) && props.panOnDrag.includes(0)
2500
2658
  })}
2501
- onClick={(e) => hasActiveSelection() ? void 0 : onClick(e)}
2502
- onPointerDown={(e) => hasActiveSelection() ? onPointerDown(e) : void 0}
2503
- onPointerMove={(e) => hasActiveSelection() ? onPointerMove(e) : void 0}
2504
- onPointerUp={(e) => hasActiveSelection() ? onPointerUp(e) : void 0}
2659
+ onClick={(e) => isSelectionEnabled() ? void 0 : onClick(e)}
2660
+ on:pointerdown={{
2661
+ capture: true,
2662
+ handleEvent: (e) => {
2663
+ if (isSelectionEnabled()) onPointerDownCapture(e);
2664
+ }
2665
+ }}
2666
+ onPointerMove={(e) => isSelectionEnabled() ? onPointerMove(e) : void 0}
2667
+ onPointerUp={onPointerUp}
2668
+ onPointerCancel={(e) => isSelectionEnabled() ? onPointerCancel(e) : void 0}
2505
2669
  onContextMenu={onContextMenu}
2506
2670
  >
2507
2671
  {props.children}
@@ -2580,7 +2744,6 @@ var Zoom = (props) => {
2580
2744
  maxZoom: store.maxZoom,
2581
2745
  translateExtent: store.translateExtent,
2582
2746
  viewport: viewPort(),
2583
- paneClickDistance: props.paneClickDistance,
2584
2747
  onDraggingChange: actions.setDragging,
2585
2748
  onPanZoomStart: props.onMoveStart,
2586
2749
  onPanZoom: props.onMove,
@@ -2598,11 +2761,12 @@ var Zoom = (props) => {
2598
2761
  createEffect5(() => {
2599
2762
  panZoomInstance.update({
2600
2763
  lib: store.lib,
2764
+ panActivationKeyPressed: store.panActivationKeyPressed,
2601
2765
  zoomActivationKeyPressed: store.zoomActivationKeyPressed,
2602
2766
  noPanClassName: store.noPanClass,
2603
2767
  noWheelClassName: store.noWheelClass,
2604
2768
  userSelectionActive: !!store.selectionRect,
2605
- panOnScrollSpeed: 0.5,
2769
+ panOnScrollSpeed: props.panOnScrollSpeed,
2606
2770
  panOnDrag: panOnDrag(),
2607
2771
  panOnScroll: panOnScroll(),
2608
2772
  zoomOnScroll: props.zoomOnScroll,
@@ -2610,6 +2774,9 @@ var Zoom = (props) => {
2610
2774
  zoomOnPinch: props.zoomOnPinch,
2611
2775
  panOnScrollMode: props.panOnScrollMode,
2612
2776
  preventScrolling: typeof props.preventScrolling === "boolean" ? props.preventScrolling : true,
2777
+ paneClickDistance: props.paneClickDistance,
2778
+ selectionOnDrag: props.selectionOnDrag,
2779
+ connectionInProgress: store.connection.inProgress,
2613
2780
  onTransformChange
2614
2781
  });
2615
2782
  });
@@ -2971,6 +3138,49 @@ var Controls = (props) => {
2971
3138
  </Panel>;
2972
3139
  };
2973
3140
 
3141
+ // src/components/graph/plugins/EdgeToolbar.tsx
3142
+ import { getEdgeToolbarTransform } from "@xyflow/system";
3143
+ import clsx15 from "clsx";
3144
+ import { Show as Show13, splitProps as splitProps8 } from "solid-js";
3145
+ var EdgeToolbar = (props) => {
3146
+ const [local, rest] = splitProps8(props, [
3147
+ "x",
3148
+ "y",
3149
+ "alignX",
3150
+ "alignY",
3151
+ "isVisible",
3152
+ "selectEdgeOnClick",
3153
+ "class",
3154
+ "children"
3155
+ ]);
3156
+ const { store, edgeLookup } = useInternalSolidFlow();
3157
+ const edgeId = useEdgeId();
3158
+ const isActive = () => typeof local.isVisible === "boolean" ? local.isVisible : !!edgeLookup.get(edgeId())?.selected;
3159
+ const transform = () => getEdgeToolbarTransform(
3160
+ local.x,
3161
+ local.y,
3162
+ store.viewport.zoom,
3163
+ local.alignX ?? "center",
3164
+ local.alignY ?? "center"
3165
+ );
3166
+ return <Show13 when={isActive()}>
3167
+ <EdgeLabel selectEdgeOnClick={local.selectEdgeOnClick} transparent>
3168
+ <div
3169
+ class={clsx15("solid-flow__edge-toolbar", local.class)}
3170
+ style={{
3171
+ position: "absolute",
3172
+ transform: transform(),
3173
+ "transform-origin": "0 0"
3174
+ }}
3175
+ data-id={edgeId()}
3176
+ {...rest}
3177
+ >
3178
+ {local.children}
3179
+ </div>
3180
+ </EdgeLabel>
3181
+ </Show13>;
3182
+ };
3183
+
2974
3184
  // src/components/graph/plugins/minimap/MiniMap.tsx
2975
3185
  import {
2976
3186
  getBoundsOfRects as getBoundsOfRects2,
@@ -2979,21 +3189,21 @@ import {
2979
3189
  nodeHasDimensions as nodeHasDimensions2,
2980
3190
  XYMinimap
2981
3191
  } from "@xyflow/system";
2982
- import clsx16 from "clsx";
3192
+ import clsx17 from "clsx";
2983
3193
  import {
2984
3194
  createEffect as createEffect6,
2985
3195
  createMemo as createMemo7,
2986
3196
  createSignal as createSignal6,
2987
3197
  Index,
2988
3198
  mergeProps as mergeProps16,
2989
- onCleanup as onCleanup4,
3199
+ onCleanup as onCleanup5,
2990
3200
  onMount as onMount3,
2991
- Show as Show13,
2992
- splitProps as splitProps8
3201
+ Show as Show14,
3202
+ splitProps as splitProps9
2993
3203
  } from "solid-js";
2994
3204
 
2995
3205
  // src/components/graph/plugins/minimap/MiniMapNode.tsx
2996
- import clsx15 from "clsx";
3206
+ import clsx16 from "clsx";
2997
3207
  import { mergeProps as mergeProps15 } from "solid-js";
2998
3208
  var MiniMapNode = (props) => {
2999
3209
  const _props = mergeProps15(
@@ -3013,7 +3223,7 @@ var MiniMapNode = (props) => {
3013
3223
  return acc;
3014
3224
  }, {});
3015
3225
  return <rect
3016
- class={clsx15("solid-flow__minimap-node", { selected: _props.selected }, _props.class)}
3226
+ class={clsx16("solid-flow__minimap-node", { selected: _props.selected }, _props.class)}
3017
3227
  x={_props.x}
3018
3228
  y={_props.y}
3019
3229
  rx={_props.borderRadius}
@@ -3044,7 +3254,7 @@ var MiniMap = (props) => {
3044
3254
  },
3045
3255
  props
3046
3256
  );
3047
- const [local, paneProps] = splitProps8(_props, [
3257
+ const [local, paneProps] = splitProps9(_props, [
3048
3258
  "class",
3049
3259
  "style",
3050
3260
  "position",
@@ -3111,14 +3321,14 @@ var MiniMap = (props) => {
3111
3321
  return <Panel
3112
3322
  position={local.position}
3113
3323
  data-testid="solid-flow__minimap"
3114
- class={clsx16(["solid-flow__minimap", local.class])}
3324
+ class={clsx17(["solid-flow__minimap", local.class])}
3115
3325
  style={{
3116
3326
  "--xy-minimap-background-color-props": local.bgColor,
3117
3327
  ...local.style
3118
3328
  }}
3119
3329
  {...paneProps}
3120
3330
  >
3121
- <Show13 when={store.panZoom}>
3331
+ <Show14 when={store.panZoom}>
3122
3332
  {(panZoom) => {
3123
3333
  const [ref, setRef] = createSignal6();
3124
3334
  onMount3(() => {
@@ -3139,7 +3349,7 @@ var MiniMap = (props) => {
3139
3349
  zoomable: local.zoomable
3140
3350
  });
3141
3351
  });
3142
- onCleanup4(() => {
3352
+ onCleanup5(() => {
3143
3353
  minimap.destroy();
3144
3354
  });
3145
3355
  });
@@ -3162,7 +3372,7 @@ var MiniMap = (props) => {
3162
3372
  {(nodeId) => {
3163
3373
  const node = createMemo7(() => nodeLookup.get(nodeId()));
3164
3374
  const nodeVisible = () => Boolean(node() && nodeHasDimensions2(node()) && !node().hidden);
3165
- return <Show13 when={nodeVisible() && getNodeDimensions3(node())}>
3375
+ return <Show14 when={nodeVisible() && getNodeDimensions3(node())}>
3166
3376
  {(nodeDimensions) => <MiniMapNode
3167
3377
  x={node().internals.positionAbsolute.x}
3168
3378
  y={node().internals.positionAbsolute.y}
@@ -3176,7 +3386,7 @@ var MiniMap = (props) => {
3176
3386
  strokeColor={nodeStrokeColorFunc().call(null, node())}
3177
3387
  class={nodeClassFunc().call(null, node())}
3178
3388
  />}
3179
- </Show13>;
3389
+ </Show14>;
3180
3390
  }}
3181
3391
  </Index>
3182
3392
  <path
@@ -3188,7 +3398,7 @@ var MiniMap = (props) => {
3188
3398
  />
3189
3399
  </svg>;
3190
3400
  }}
3191
- </Show13>
3401
+ </Show14>
3192
3402
  </Panel>;
3193
3403
  };
3194
3404
 
@@ -3197,19 +3407,19 @@ import {
3197
3407
  XY_RESIZER_HANDLE_POSITIONS,
3198
3408
  XY_RESIZER_LINE_POSITIONS
3199
3409
  } from "@xyflow/system";
3200
- import { For as For4, mergeProps as mergeProps18, Show as Show14, splitProps as splitProps10 } from "solid-js";
3410
+ import { For as For4, mergeProps as mergeProps18, Show as Show15, splitProps as splitProps11 } from "solid-js";
3201
3411
 
3202
3412
  // src/components/graph/plugins/nodeResizer/ResizeControl.tsx
3203
3413
  import {
3204
3414
  XYResizer
3205
3415
  } from "@xyflow/system";
3206
- import clsx17 from "clsx";
3416
+ import clsx18 from "clsx";
3207
3417
  import {
3208
3418
  createEffect as createEffect7,
3209
3419
  mergeProps as mergeProps17,
3210
- onCleanup as onCleanup5,
3420
+ onCleanup as onCleanup6,
3211
3421
  onMount as onMount4,
3212
- splitProps as splitProps9
3422
+ splitProps as splitProps10
3213
3423
  } from "solid-js";
3214
3424
  import { produce as produce3 } from "solid-js/store";
3215
3425
  var ResizeControl = (props) => {
@@ -3226,7 +3436,7 @@ var ResizeControl = (props) => {
3226
3436
  },
3227
3437
  props
3228
3438
  );
3229
- const [local, rest] = splitProps9(_props, [
3439
+ const [local, rest] = splitProps10(_props, [
3230
3440
  "nodeId",
3231
3441
  "variant",
3232
3442
  "position",
@@ -3303,13 +3513,13 @@ var ResizeControl = (props) => {
3303
3513
  shouldResize: local.shouldResize
3304
3514
  });
3305
3515
  });
3306
- onCleanup5(() => {
3516
+ onCleanup6(() => {
3307
3517
  resizer.destroy();
3308
3518
  });
3309
3519
  });
3310
3520
  return <div
3311
3521
  ref={resizeControlRef}
3312
- class={clsx17([
3522
+ class={clsx18([
3313
3523
  "solid-flow__resize-control",
3314
3524
  local.variant,
3315
3525
  store.noDragClass,
@@ -3337,8 +3547,8 @@ var NodeResizer = (props) => {
3337
3547
  },
3338
3548
  props
3339
3549
  );
3340
- const [local, rest] = splitProps10(props, ["handleClass", "handleStyle", "lineClass", "lineStyle"]);
3341
- return <Show14 when={_props.visible}>
3550
+ const [local, rest] = splitProps11(props, ["handleClass", "handleStyle", "lineClass", "lineStyle"]);
3551
+ return <Show15 when={_props.visible}>
3342
3552
  <For4 each={XY_RESIZER_LINE_POSITIONS}>
3343
3553
  {(position) => <ResizeControl
3344
3554
  variant="line"
@@ -3356,14 +3566,20 @@ var NodeResizer = (props) => {
3356
3566
  {...rest}
3357
3567
  />}
3358
3568
  </For4>
3359
- </Show14>;
3569
+ </Show15>;
3360
3570
  };
3361
3571
 
3362
3572
  // src/components/graph/plugins/NodeToolbar.tsx
3363
3573
  import { getNodeToolbarTransform } from "@xyflow/system";
3364
- import { mergeProps as mergeProps19, Show as Show15, splitProps as splitProps11, useContext as useContext6 } from "solid-js";
3574
+ import { mergeProps as mergeProps19, Show as Show16, splitProps as splitProps12, useContext as useContext6 } from "solid-js";
3365
3575
  import { Portal as Portal3 } from "solid-js/web";
3366
3576
 
3577
+ // src/hooks/useColorMode.ts
3578
+ function useColorMode() {
3579
+ const { store } = useInternalSolidFlow();
3580
+ return () => store.colorMode;
3581
+ }
3582
+
3367
3583
  // src/hooks/useConnection.tsx
3368
3584
  function useConnection() {
3369
3585
  const { store } = useInternalSolidFlow();
@@ -3410,6 +3626,16 @@ function useHandleEdgeSelect() {
3410
3626
  };
3411
3627
  }
3412
3628
 
3629
+ // src/hooks/useInitialized.ts
3630
+ function useNodesInitialized() {
3631
+ const { store } = useInternalSolidFlow();
3632
+ return () => store.nodesInitialized;
3633
+ }
3634
+ function useViewportInitialized() {
3635
+ const { store } = useInternalSolidFlow();
3636
+ return () => store.viewportInitialized;
3637
+ }
3638
+
3413
3639
  // src/hooks/useInternalNode.tsx
3414
3640
  function useInternalNode(id) {
3415
3641
  const { nodeLookup } = useInternalSolidFlow();
@@ -3478,8 +3704,8 @@ import {
3478
3704
  getViewportForBounds as getViewportForBounds2,
3479
3705
  isRectObject,
3480
3706
  nodeToRect as nodeToRect2,
3481
- pointToRendererPoint as pointToRendererPoint2,
3482
- rendererPointToPoint
3707
+ pointToRendererPoint as pointToRendererPoint3,
3708
+ rendererPointToPoint as rendererPointToPoint2
3483
3709
  } from "@xyflow/system";
3484
3710
  import { batch as batch7 } from "solid-js";
3485
3711
  import { unwrap as unwrap2 } from "solid-js/store";
@@ -3648,7 +3874,7 @@ function useSolidFlow() {
3648
3874
  x: position.x - domX,
3649
3875
  y: position.y - domY
3650
3876
  };
3651
- return pointToRendererPoint2(
3877
+ return pointToRendererPoint3(
3652
3878
  correctedPosition,
3653
3879
  [x, y, zoom],
3654
3880
  _snapGrid !== null,
@@ -3666,7 +3892,7 @@ function useSolidFlow() {
3666
3892
  }
3667
3893
  const { x, y, zoom } = store.viewport;
3668
3894
  const { x: domX, y: domY } = store.domNode.getBoundingClientRect();
3669
- const rendererPosition = rendererPointToPoint(position, [x, y, zoom]);
3895
+ const rendererPosition = rendererPointToPoint2(position, [x, y, zoom]);
3670
3896
  return {
3671
3897
  x: rendererPosition.x + domX,
3672
3898
  y: rendererPosition.y + domY
@@ -3741,7 +3967,7 @@ var NodeToolbar = (props) => {
3741
3967
  },
3742
3968
  props
3743
3969
  );
3744
- const [local, divProps] = splitProps11(_props, [
3970
+ const [local, divProps] = splitProps12(_props, [
3745
3971
  "nodeId",
3746
3972
  "position",
3747
3973
  "align",
@@ -3782,7 +4008,7 @@ var NodeToolbar = (props) => {
3782
4008
  return typeof local.isVisible === "boolean" ? local.isVisible : nodes.length === 1 && Boolean(nodes[0].selected) && selectedNodesCount() === 1;
3783
4009
  };
3784
4010
  const showPortal = () => Boolean(store.domNode && isActive() && toolbarNodes().length > 0);
3785
- return <Show15 when={showPortal()}>
4011
+ return <Show16 when={showPortal()}>
3786
4012
  <Portal3 mount={store.domNode}>
3787
4013
  <div
3788
4014
  class="solid-flow__node-toolbar"
@@ -3799,16 +4025,16 @@ var NodeToolbar = (props) => {
3799
4025
  {local.children}
3800
4026
  </div>
3801
4027
  </Portal3>
3802
- </Show15>;
4028
+ </Show16>;
3803
4029
  };
3804
4030
 
3805
4031
  // src/components/graph/selection/NodeSelection.tsx
3806
4032
  import { getInternalNodesBounds as getInternalNodesBounds3, isNumeric as isNumeric2 } from "@xyflow/system";
3807
- import clsx18 from "clsx";
3808
- import { createEffect as createEffect9, createSignal as createSignal8, Show as Show17 } from "solid-js";
4033
+ import clsx19 from "clsx";
4034
+ import { createEffect as createEffect9, createSignal as createSignal8, Show as Show18 } from "solid-js";
3809
4035
 
3810
4036
  // src/components/graph/selection/Selection.tsx
3811
- import { mergeProps as mergeProps20, Show as Show16 } from "solid-js";
4037
+ import { mergeProps as mergeProps20, Show as Show17 } from "solid-js";
3812
4038
  var Selection = (props) => {
3813
4039
  const _props = mergeProps20({ isVisible: true }, props);
3814
4040
  const styles = () => ({
@@ -3822,9 +4048,9 @@ var Selection = (props) => {
3822
4048
  transform: `translate(${props.x}px, ${props.y}px)`
3823
4049
  }
3824
4050
  });
3825
- return <Show16 when={_props.isVisible}>
4051
+ return <Show17 when={_props.isVisible}>
3826
4052
  <div class="solid-flow__selection" style={styles()} />
3827
- </Show16>;
4053
+ </Show17>;
3828
4054
  };
3829
4055
 
3830
4056
  // src/components/graph/selection/NodeSelection.tsx
@@ -3870,12 +4096,12 @@ var NodeSelection = (props) => {
3870
4096
  event.preventDefault();
3871
4097
  actions.moveSelectedNodes(diff, event.shiftKey ? 4 : 1);
3872
4098
  };
3873
- return <Show17
4099
+ return <Show18
3874
4100
  when={store.selectionRectMode === "nodes" && bounds() && isNumeric2(bounds()?.x) && isNumeric2(bounds()?.y)}
3875
4101
  >
3876
4102
  <div
3877
4103
  ref={setRef}
3878
- class={clsx18("solid-flow__selection-wrapper", store.noPanClass)}
4104
+ class={clsx19("solid-flow__selection-wrapper", store.noPanClass)}
3879
4105
  style={{
3880
4106
  width: toPxString(bounds()?.width),
3881
4107
  height: toPxString(bounds()?.height),
@@ -3889,27 +4115,29 @@ var NodeSelection = (props) => {
3889
4115
  >
3890
4116
  <Selection width="100%" height="100%" x={0} y={0} />
3891
4117
  </div>
3892
- </Show17>;
4118
+ </Show18>;
3893
4119
  };
3894
4120
 
3895
4121
  // src/components/SolidFlow/component.tsx
3896
4122
  import { createResizeObserver } from "@solid-primitives/resize-observer";
3897
4123
  import { infiniteExtent as infiniteExtent4, isMacOs as isMacOs2 } from "@xyflow/system";
3898
- import clsx19 from "clsx";
4124
+ import clsx20 from "clsx";
3899
4125
  import {
3900
4126
  batch as batch9,
3901
4127
  createEffect as createEffect10,
4128
+ createMemo as createMemo9,
3902
4129
  mergeProps as mergeProps22,
3903
- onCleanup as onCleanup7,
4130
+ onCleanup as onCleanup8,
3904
4131
  onMount as onMount6,
3905
- splitProps as splitProps12,
4132
+ splitProps as splitProps13,
4133
+ untrack as untrack2,
3906
4134
  useContext as useContext7
3907
4135
  } from "solid-js";
3908
4136
 
3909
4137
  // src/components/utility/Attribution.tsx
3910
- import { Show as Show18 } from "solid-js";
4138
+ import { Show as Show19 } from "solid-js";
3911
4139
  var Attribution = (props) => {
3912
- return <Show18 when={!props.proOptions?.hideAttribution}>
4140
+ return <Show19 when={!props.proOptions?.hideAttribution}>
3913
4141
  <Panel
3914
4142
  position={props.position ?? "bottom-right"}
3915
4143
  class="solid-flow__attribution"
@@ -3924,12 +4152,12 @@ var Attribution = (props) => {
3924
4152
  Solid Flow
3925
4153
  </a>
3926
4154
  </Panel>
3927
- </Show18>;
4155
+ </Show19>;
3928
4156
  };
3929
4157
 
3930
4158
  // src/components/utility/KeyHandler.tsx
3931
4159
  import { isInputDOMNode as isInputDOMNode2, isMacOs } from "@xyflow/system";
3932
- import { batch as batch8, mergeProps as mergeProps21, onCleanup as onCleanup6, onMount as onMount5 } from "solid-js";
4160
+ import { batch as batch8, mergeProps as mergeProps21, onCleanup as onCleanup7, onMount as onMount5 } from "solid-js";
3933
4161
  function isKeyObject(key) {
3934
4162
  return key !== null && typeof key === "object";
3935
4163
  }
@@ -4055,7 +4283,7 @@ var KeyHandler = (props) => {
4055
4283
  window.addEventListener("keyup", handleKeyUp);
4056
4284
  window.addEventListener("blur", resetKeysAndSelection);
4057
4285
  window.addEventListener("contextmenu", resetKeysAndSelection);
4058
- onCleanup6(() => {
4286
+ onCleanup7(() => {
4059
4287
  window.removeEventListener("keydown", handleKeyDown);
4060
4288
  window.removeEventListener("keyup", handleKeyUp);
4061
4289
  window.removeEventListener("blur", resetKeysAndSelection);
@@ -4094,7 +4322,7 @@ var SolidFlow = (props) => {
4094
4322
  },
4095
4323
  props
4096
4324
  );
4097
- const [flowProps, htmlProps] = splitProps12(_props, [
4325
+ const [flowProps, htmlProps] = splitProps13(_props, [
4098
4326
  // Core flow props
4099
4327
  "nodes",
4100
4328
  "edges",
@@ -4111,6 +4339,7 @@ var SolidFlow = (props) => {
4111
4339
  "nodeClickDistance",
4112
4340
  "minZoom",
4113
4341
  "maxZoom",
4342
+ "zIndexMode",
4114
4343
  "initialViewport",
4115
4344
  "viewport",
4116
4345
  "translateExtent",
@@ -4135,6 +4364,7 @@ var SolidFlow = (props) => {
4135
4364
  "autoPanOnConnect",
4136
4365
  "autoPanOnNodeDrag",
4137
4366
  "autoPanOnNodeFocus",
4367
+ "autoPanOnSelection",
4138
4368
  "autoPanSpeed",
4139
4369
  // Connection and validation
4140
4370
  "connectionRadius",
@@ -4244,10 +4474,21 @@ var SolidFlow = (props) => {
4244
4474
  createEffect10(() => {
4245
4475
  actions.setPaneClickDistance(flowProps.paneClickDistance);
4246
4476
  });
4247
- onCleanup7(() => {
4477
+ onCleanup8(() => {
4248
4478
  actions.reset();
4249
4479
  });
4250
4480
  });
4481
+ const selectedElements = createMemo9(
4482
+ () => ({ nodes: store.selectedNodes, edges: store.selectedEdges }),
4483
+ void 0,
4484
+ {
4485
+ equals: (a, b) => a.nodes.length === b.nodes.length && a.edges.length === b.edges.length && a.nodes.every((node, i) => node.id === b.nodes[i].id) && a.edges.every((edge, i) => edge.id === b.edges[i].id)
4486
+ }
4487
+ );
4488
+ createEffect10(() => {
4489
+ const params = selectedElements();
4490
+ untrack2(() => flowProps.onSelectionChange)?.(params);
4491
+ });
4251
4492
  const rootStyle = () => ({
4252
4493
  width: toPxString(flowProps.width),
4253
4494
  height: toPxString(flowProps.height),
@@ -4257,7 +4498,7 @@ var SolidFlow = (props) => {
4257
4498
  role="application"
4258
4499
  data-testid="solid-flow__wrapper"
4259
4500
  ref={domNode}
4260
- class={clsx19(["solid-flow", "solid-flow__container", flowProps.class, store.colorMode])}
4501
+ class={clsx20(["solid-flow", "solid-flow__container", flowProps.class, store.colorMode])}
4261
4502
  style={rootStyle()}
4262
4503
  onScroll={(e) => {
4263
4504
  e.currentTarget.scrollTo({ top: 0, left: 0, behavior: "auto" });
@@ -4279,8 +4520,10 @@ var SolidFlow = (props) => {
4279
4520
  zoomOnDoubleClick={flowProps.zoomOnDoubleClick}
4280
4521
  zoomOnPinch={flowProps.zoomOnPinch}
4281
4522
  panOnScroll={flowProps.panOnScroll}
4523
+ panOnScrollSpeed={flowProps.panOnScrollSpeed}
4282
4524
  panOnDrag={flowProps.panOnDrag}
4283
4525
  paneClickDistance={flowProps.paneClickDistance}
4526
+ selectionOnDrag={flowProps.selectionOnDrag}
4284
4527
  onMoveStart={flowProps.onMoveStart}
4285
4528
  onMove={flowProps.onMove}
4286
4529
  onMoveEnd={flowProps.onMoveEnd}
@@ -4294,6 +4537,8 @@ var SolidFlow = (props) => {
4294
4537
  onSelectionEnd={flowProps.onSelectionEnd}
4295
4538
  panOnDrag={flowProps.panOnDrag}
4296
4539
  selectionOnDrag={flowProps.selectionOnDrag}
4540
+ paneClickDistance={flowProps.paneClickDistance}
4541
+ autoPanOnSelection={flowProps.autoPanOnSelection}
4297
4542
  >
4298
4543
  <Viewport>
4299
4544
  <div class="solid-flow__container solid-flow__viewport-back" />
@@ -4348,11 +4593,11 @@ var SolidFlow = (props) => {
4348
4593
  };
4349
4594
 
4350
4595
  // src/components/SolidFlow/provider.tsx
4351
- import { mergeProps as mergeProps23, onCleanup as onCleanup8 } from "solid-js";
4596
+ import { mergeProps as mergeProps23, onCleanup as onCleanup9 } from "solid-js";
4352
4597
  var SolidFlowProvider = (props) => {
4353
4598
  const _props = mergeProps23(getDefaultFlowStateProps(), props);
4354
4599
  const solidFlow = createSolidFlow(_props);
4355
- onCleanup8(() => {
4600
+ onCleanup9(() => {
4356
4601
  solidFlow.actions.reset();
4357
4602
  });
4358
4603
  const ContextProvider = SolidFlowContext.Provider;
@@ -4411,6 +4656,7 @@ export {
4411
4656
  EdgeLabelRenderer,
4412
4657
  EdgeReconnectAnchor,
4413
4658
  EdgeRenderer,
4659
+ EdgeToolbar,
4414
4660
  EdgeWrapper,
4415
4661
  GroupNode,
4416
4662
  Handle,
@@ -4457,6 +4703,7 @@ export {
4457
4703
  getSmoothStepPath6 as getSmoothStepPath,
4458
4704
  getStraightPath4 as getStraightPath,
4459
4705
  getViewportForBounds3 as getViewportForBounds,
4706
+ useColorMode,
4460
4707
  useConnection,
4461
4708
  useEdges,
4462
4709
  useHandleEdgeSelect,
@@ -4464,7 +4711,9 @@ export {
4464
4711
  useNodeConnections,
4465
4712
  useNodes,
4466
4713
  useNodesData,
4714
+ useNodesInitialized,
4467
4715
  useSolidFlow,
4468
4716
  useUpdateNodeInternals,
4469
- useViewport
4717
+ useViewport,
4718
+ useViewportInitialized
4470
4719
  };