@dschz/solid-flow 1.0.0-next.6 → 1.0.0-next.7
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/README.md +27 -0
- package/dist/index/index.d.ts +131 -102
- package/dist/index/index.js +471 -259
- package/dist/index/index.jsx +470 -250
- package/package.json +6 -5
package/dist/index/index.js
CHANGED
|
@@ -65,7 +65,7 @@ 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
|
-
}, EdgeLabelRenderer = (props) => {
|
|
68
|
+
}, isEdgeSelectable = (edge, store) => edge.selectable ?? store.defaultEdgeOptions.selectable ?? store.elementsSelectable, EdgeLabelRenderer = (props) => {
|
|
69
69
|
let { store } = useInternalSolidFlow(), labelNode = () => store.domNode?.querySelector(".solid-flow__edge-labels");
|
|
70
70
|
return createComponent(Show, {
|
|
71
71
|
get when() {
|
|
@@ -282,6 +282,181 @@ const BaseEdge = (props) => {
|
|
|
282
282
|
});
|
|
283
283
|
};
|
|
284
284
|
//#endregion
|
|
285
|
+
//#region src/core/spatial/grid.ts
|
|
286
|
+
/**
|
|
287
|
+
* A uniform spatial hash over axis-aligned rects — the plain, NON-reactive
|
|
288
|
+
* building block behind the flow's spatial queries (RFC-4239 dossier:
|
|
289
|
+
* gesture-scoped snapshots and epoch-rebuilt indexes; deliberately never a
|
|
290
|
+
* live-maintained reactive structure, which would re-create the round-6
|
|
291
|
+
* central-collection anti-pattern).
|
|
292
|
+
*
|
|
293
|
+
* Every operation is O(cells touched); with cellSize on the order of the
|
|
294
|
+
* query radius or median node size, inserts and queries touch O(1) cells.
|
|
295
|
+
* No balancing, no extent-known-up-front requirement, no dependency —
|
|
296
|
+
* upstream's own bake-off (quadtree vs BVH vs rbush) is why: fixed-radius
|
|
297
|
+
* neighborhood and rect-vs-box queries are the textbook grid case.
|
|
298
|
+
*/
|
|
299
|
+
var SpatialGrid = class {
|
|
300
|
+
cellSize;
|
|
301
|
+
cells = /* @__PURE__ */ new Map();
|
|
302
|
+
rects = /* @__PURE__ */ new Map();
|
|
303
|
+
constructor(cellSize) {
|
|
304
|
+
this.cellSize = cellSize;
|
|
305
|
+
}
|
|
306
|
+
cellRange(rect) {
|
|
307
|
+
let size = this.cellSize;
|
|
308
|
+
return {
|
|
309
|
+
minX: Math.floor(rect.x / size),
|
|
310
|
+
maxX: Math.floor((rect.x + rect.width) / size),
|
|
311
|
+
minY: Math.floor(rect.y / size),
|
|
312
|
+
maxY: Math.floor((rect.y + rect.height) / size)
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
insert(id, rect) {
|
|
316
|
+
this.rects.set(id, rect);
|
|
317
|
+
let { minX, maxX, minY, maxY } = this.cellRange(rect);
|
|
318
|
+
for (let cx = minX; cx <= maxX; cx++) for (let cy = minY; cy <= maxY; cy++) {
|
|
319
|
+
let key = `${cx}:${cy}`, bucket = this.cells.get(key);
|
|
320
|
+
bucket ? bucket.push(id) : this.cells.set(key, [id]);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/** Ids of entries whose rect overlaps the query rect (touching counts). */
|
|
324
|
+
queryRect(query) {
|
|
325
|
+
let { minX, maxX, minY, maxY } = this.cellRange(query), seen = /* @__PURE__ */ new Set(), result = [];
|
|
326
|
+
for (let cx = minX; cx <= maxX; cx++) for (let cy = minY; cy <= maxY; cy++) {
|
|
327
|
+
let bucket = this.cells.get(`${cx}:${cy}`);
|
|
328
|
+
if (bucket) for (let id of bucket) {
|
|
329
|
+
if (seen.has(id)) continue;
|
|
330
|
+
seen.add(id);
|
|
331
|
+
let rect = this.rects.get(id);
|
|
332
|
+
rect.x <= query.x + query.width && rect.x + rect.width >= query.x && rect.y <= query.y + query.height && rect.y + rect.height >= query.y && result.push(id);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return result;
|
|
336
|
+
}
|
|
337
|
+
get size() {
|
|
338
|
+
return this.rects.size;
|
|
339
|
+
}
|
|
340
|
+
}, GestureSpatialLookup = class {
|
|
341
|
+
#real;
|
|
342
|
+
#cellSize;
|
|
343
|
+
#grid = null;
|
|
344
|
+
#queryRect = null;
|
|
345
|
+
constructor(real, cellSize) {
|
|
346
|
+
this.#real = real, this.#cellSize = cellSize;
|
|
347
|
+
}
|
|
348
|
+
/** Snapshot the current geometry into the grid (gesture start). */
|
|
349
|
+
arm(rectOf) {
|
|
350
|
+
let grid = new SpatialGrid(this.#cellSize);
|
|
351
|
+
for (let [id, value] of this.#real.entries()) grid.insert(id, rectOf(value));
|
|
352
|
+
this.#grid = grid, this.#queryRect = null;
|
|
353
|
+
}
|
|
354
|
+
/** Focus iteration on the neighborhood of the pointer (per move). */
|
|
355
|
+
setQueryCenter(center, radius) {
|
|
356
|
+
this.#queryRect = {
|
|
357
|
+
x: center.x - radius,
|
|
358
|
+
y: center.y - radius,
|
|
359
|
+
width: radius * 2,
|
|
360
|
+
height: radius * 2
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
/** Focus iteration on an explicit rect (box-selection gestures). */
|
|
364
|
+
setQueryRect(rect) {
|
|
365
|
+
this.#queryRect = rect;
|
|
366
|
+
}
|
|
367
|
+
/** Back to plain pass-through (gesture end). */
|
|
368
|
+
disarm() {
|
|
369
|
+
this.#grid = null, this.#queryRect = null;
|
|
370
|
+
}
|
|
371
|
+
#candidateIds() {
|
|
372
|
+
return !this.#grid || !this.#queryRect ? null : this.#grid.queryRect(this.#queryRect);
|
|
373
|
+
}
|
|
374
|
+
get(key) {
|
|
375
|
+
return this.#real.get(key);
|
|
376
|
+
}
|
|
377
|
+
has(key) {
|
|
378
|
+
return this.#real.has(key);
|
|
379
|
+
}
|
|
380
|
+
get size() {
|
|
381
|
+
return this.#real.size;
|
|
382
|
+
}
|
|
383
|
+
*keys() {
|
|
384
|
+
let candidates = this.#candidateIds();
|
|
385
|
+
if (!candidates) {
|
|
386
|
+
yield* this.#real.keys();
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
for (let id of candidates) this.#real.has(id) && (yield id);
|
|
390
|
+
}
|
|
391
|
+
*values() {
|
|
392
|
+
let candidates = this.#candidateIds();
|
|
393
|
+
if (!candidates) {
|
|
394
|
+
yield* this.#real.values();
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
for (let id of candidates) {
|
|
398
|
+
let value = this.#real.get(id);
|
|
399
|
+
value !== void 0 && (yield value);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
*entries() {
|
|
403
|
+
let candidates = this.#candidateIds();
|
|
404
|
+
if (!candidates) {
|
|
405
|
+
yield* this.#real.entries();
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
for (let id of candidates) {
|
|
409
|
+
let value = this.#real.get(id);
|
|
410
|
+
value !== void 0 && (yield [id, value]);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
[Symbol.iterator]() {
|
|
414
|
+
return this.entries();
|
|
415
|
+
}
|
|
416
|
+
forEach(callback, thisArg) {
|
|
417
|
+
for (let [key, value] of this.entries()) callback.call(thisArg, value, key, this);
|
|
418
|
+
}
|
|
419
|
+
[Symbol.toStringTag] = "GestureSpatialLookup";
|
|
420
|
+
set() {
|
|
421
|
+
throw Error("GestureSpatialLookup is read-only");
|
|
422
|
+
}
|
|
423
|
+
getOrInsert() {
|
|
424
|
+
throw Error("GestureSpatialLookup is read-only");
|
|
425
|
+
}
|
|
426
|
+
getOrInsertComputed() {
|
|
427
|
+
throw Error("GestureSpatialLookup is read-only");
|
|
428
|
+
}
|
|
429
|
+
delete() {
|
|
430
|
+
throw Error("GestureSpatialLookup is read-only");
|
|
431
|
+
}
|
|
432
|
+
clear() {
|
|
433
|
+
throw Error("GestureSpatialLookup is read-only");
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
//#endregion
|
|
437
|
+
//#region src/components/handle/connectionGestureLookup.ts
|
|
438
|
+
/**
|
|
439
|
+
* Upstream `getClosestHandle` prefilters nodes within
|
|
440
|
+
* `connectionRadius + ADDITIONAL_DISTANCE` of the pointer; ADDITIONAL_DISTANCE
|
|
441
|
+
* is hardcoded to 250 in @xyflow/system (xyhandle/utils.ts). Tracked here with
|
|
442
|
+
* a safety pad: a superset of candidates is always correct (their exact
|
|
443
|
+
* distance filter runs after), so the pad only costs a few extra candidates.
|
|
444
|
+
*/
|
|
445
|
+
const armConnectionGestureLookup = (options) => {
|
|
446
|
+
let { event, real, domNode, getTransform, connectionRadius } = options, containerBounds = domNode?.getBoundingClientRect();
|
|
447
|
+
if (!containerBounds) return real;
|
|
448
|
+
let radius = connectionRadius + 250 + 50, lookup = new GestureSpatialLookup(real, radius);
|
|
449
|
+
lookup.arm((node) => nodeToRect(node));
|
|
450
|
+
let update = (moveEvent) => {
|
|
451
|
+
lookup.setQueryCenter(pointToRendererPoint(getEventPosition(moveEvent, containerBounds), getTransform(), !1, [1, 1]), radius);
|
|
452
|
+
};
|
|
453
|
+
update(event);
|
|
454
|
+
let doc = getHostForElement(event.target), dispose = () => {
|
|
455
|
+
doc.removeEventListener("mousemove", update, !0), doc.removeEventListener("touchmove", update, !0), doc.removeEventListener("mouseup", dispose, !0), doc.removeEventListener("touchend", dispose, !0), lookup.disarm();
|
|
456
|
+
};
|
|
457
|
+
return doc.addEventListener("mousemove", update, !0), doc.addEventListener("touchmove", update, !0), doc.addEventListener("mouseup", dispose, !0), doc.addEventListener("touchend", dispose, !0), lookup;
|
|
458
|
+
};
|
|
459
|
+
//#endregion
|
|
285
460
|
//#region src/components/edge/EdgeReconnectAnchor.tsx
|
|
286
461
|
var _tmpl$$32 = /* @__PURE__ */ template("<div style=background:transparent;border:none;cursor:move>");
|
|
287
462
|
/** Grab area that lets an edge end be dragged off its handle and reconnected. */
|
|
@@ -305,7 +480,13 @@ const EdgeReconnectAnchor = (props) => {
|
|
|
305
480
|
nodeId: edge().target,
|
|
306
481
|
handleId: edge().targetHandle ?? null,
|
|
307
482
|
type: "target"
|
|
308
|
-
}
|
|
483
|
+
}, gestureLookup = armConnectionGestureLookup({
|
|
484
|
+
event,
|
|
485
|
+
real: nodeLookup,
|
|
486
|
+
domNode: store.domNode,
|
|
487
|
+
getTransform: () => store.transform,
|
|
488
|
+
connectionRadius: store.connectionRadius
|
|
489
|
+
});
|
|
309
490
|
XYHandle.onPointerDown(event, {
|
|
310
491
|
lib: store.lib,
|
|
311
492
|
flowId: store.id,
|
|
@@ -315,7 +496,7 @@ const EdgeReconnectAnchor = (props) => {
|
|
|
315
496
|
autoPanOnConnect: store.autoPanOnConnect,
|
|
316
497
|
connectionMode: store.connectionMode,
|
|
317
498
|
connectionRadius: store.connectionRadius,
|
|
318
|
-
nodeLookup,
|
|
499
|
+
nodeLookup: gestureLookup,
|
|
319
500
|
isTarget: opposite.type === "target",
|
|
320
501
|
edgeUpdaterType: opposite.type,
|
|
321
502
|
cancelConnection: actions.cancelConnection,
|
|
@@ -416,9 +597,73 @@ const A11yDescriptions = () => {
|
|
|
416
597
|
}
|
|
417
598
|
})
|
|
418
599
|
];
|
|
419
|
-
},
|
|
420
|
-
let
|
|
421
|
-
|
|
600
|
+
}, createSelectionCommands = ({ store, setNodesStore, setEdgesStore, setSelectionRect, setSelectionRectMode, nodeLookup, edgeLookup, updateNodePositions }) => {
|
|
601
|
+
let unselectNodesAndEdges = ({ nodes: _nodes, edges } = {}) => {
|
|
602
|
+
let nodesToUnselect = new Set((_nodes || store.nodes).map(({ id }) => id));
|
|
603
|
+
nodesToUnselect.size && setNodesStore((nodes) => {
|
|
604
|
+
for (let node of nodes) nodesToUnselect.has(node.id) && (node.selected = !1);
|
|
605
|
+
});
|
|
606
|
+
let edgesToUnselect = new Set((edges ?? store.edges).map(({ id }) => id));
|
|
607
|
+
edgesToUnselect.size && setEdgesStore((edges) => {
|
|
608
|
+
for (let edge of edges) edgesToUnselect.has(edge.id) && (edge.selected = !1);
|
|
609
|
+
}), flush();
|
|
610
|
+
}, addSelectedNodes = (ids) => {
|
|
611
|
+
let isMultiSelection = store.multiselectionKeyPressed, idSet = new Set(ids);
|
|
612
|
+
setNodesStore((nodes) => {
|
|
613
|
+
for (let node of nodes) {
|
|
614
|
+
let nodeWillBeSelected = idSet.has(node.id), selected = isMultiSelection && node.selected || nodeWillBeSelected;
|
|
615
|
+
node.selected !== selected && (node.selected = selected);
|
|
616
|
+
}
|
|
617
|
+
}), isMultiSelection || unselectNodesAndEdges({ nodes: [] }), flush();
|
|
618
|
+
}, addSelectedEdges = (ids) => {
|
|
619
|
+
let isMultiSelection = store.multiselectionKeyPressed, idSet = new Set(ids);
|
|
620
|
+
setEdgesStore((edges) => {
|
|
621
|
+
for (let edge of edges) {
|
|
622
|
+
let edgeWillBeSelected = idSet.has(edge.id), selected = isMultiSelection && edge.selected || edgeWillBeSelected;
|
|
623
|
+
edge.selected !== selected && (edge.selected = selected);
|
|
624
|
+
}
|
|
625
|
+
}), isMultiSelection || unselectNodesAndEdges({ edges: [] }), flush();
|
|
626
|
+
};
|
|
627
|
+
return {
|
|
628
|
+
unselectNodesAndEdges,
|
|
629
|
+
addSelectedNodes,
|
|
630
|
+
addSelectedEdges,
|
|
631
|
+
handleNodeSelection: (id, unselect, nodeRef) => {
|
|
632
|
+
let node = store.nodes.find((n) => n.id === id);
|
|
633
|
+
node && (setSelectionRect(void 0), setSelectionRectMode(void 0), node.selected ? (unselect || node.selected && store.multiselectionKeyPressed) && (unselectNodesAndEdges({
|
|
634
|
+
nodes: [node],
|
|
635
|
+
edges: []
|
|
636
|
+
}), requestAnimationFrame(() => nodeRef?.blur())) : addSelectedNodes([id]));
|
|
637
|
+
},
|
|
638
|
+
handleEdgeSelection: (id) => {
|
|
639
|
+
let edge = edgeLookup[id];
|
|
640
|
+
edge && isEdgeSelectable(edge, store) && (setSelectionRect(void 0), setSelectionRectMode(void 0), edge.selected ? edge.selected && store.multiselectionKeyPressed && unselectNodesAndEdges({
|
|
641
|
+
nodes: [],
|
|
642
|
+
edges: [edge]
|
|
643
|
+
}) : addSelectedEdges([id]));
|
|
644
|
+
},
|
|
645
|
+
moveSelectedNodes: (direction, factor) => {
|
|
646
|
+
let nodeUpdates = /* @__PURE__ */ new Map(), xVelo = store.snapGrid?.[0] ?? 5, yVelo = store.snapGrid?.[1] ?? 5, xDiff = direction.x * xVelo * factor, yDiff = direction.y * yVelo * factor;
|
|
647
|
+
for (let node of nodeLookup.values()) {
|
|
648
|
+
if (!(node.selected && (node.draggable || store.nodesDraggable && node.draggable === void 0))) continue;
|
|
649
|
+
let nextPosition = {
|
|
650
|
+
x: node.internals.positionAbsolute.x + xDiff,
|
|
651
|
+
y: node.internals.positionAbsolute.y + yDiff
|
|
652
|
+
};
|
|
653
|
+
store.snapGrid && (nextPosition = snapPosition(nextPosition, store.snapGrid));
|
|
654
|
+
let { position } = calculateNodePosition({
|
|
655
|
+
nodeId: node.id,
|
|
656
|
+
nextPosition,
|
|
657
|
+
nodeLookup,
|
|
658
|
+
nodeExtent: store.nodeExtent,
|
|
659
|
+
nodeOrigin: store.nodeOrigin,
|
|
660
|
+
onError: store.onError
|
|
661
|
+
});
|
|
662
|
+
nodeUpdates.set(node.id, { position });
|
|
663
|
+
}
|
|
664
|
+
updateNodePositions(nodeUpdates);
|
|
665
|
+
}
|
|
666
|
+
};
|
|
422
667
|
}, STEP = .5 / 2, rectsEqual = (a, b) => a === b || !!a && !!b && a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height, rectsOverlap = (a, b) => a.x <= b.x + b.width && a.x + a.width >= b.x && a.y <= b.y + b.height && a.y + a.height >= b.y, createCullingViewport = (source) => createMemo(() => {
|
|
423
668
|
let { width, height } = source;
|
|
424
669
|
if (!width || !height) return null;
|
|
@@ -549,14 +794,48 @@ var RecordMapFacade = class {
|
|
|
549
794
|
}
|
|
550
795
|
};
|
|
551
796
|
//#endregion
|
|
552
|
-
//#region src/core/
|
|
797
|
+
//#region src/core/measurementIngest.ts
|
|
553
798
|
/**
|
|
554
|
-
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
*
|
|
799
|
+
* The measurement ingest lifecycle (WP3): everything that flows FROM the DOM
|
|
800
|
+
* measuring pass INTO the data graph, plus the garbage collection that keeps
|
|
801
|
+
* the measurements root aligned with graph membership. The DOM side (resize
|
|
802
|
+
* observers, the idle-scheduled measuring pass) lives in createSolidFlow;
|
|
803
|
+
* headless usage never calls these.
|
|
558
804
|
*/
|
|
559
|
-
const
|
|
805
|
+
const createMeasurementIngest = ({ setMeasurementsStore, setNodesStore, nodes }) => (createEffect(() => new Set(nodes().map((n) => n.id)), (currentIds) => {
|
|
806
|
+
setMeasurementsStore((draft) => {
|
|
807
|
+
for (let id of Object.keys(draft)) currentIds.has(id) || delete draft[id];
|
|
808
|
+
});
|
|
809
|
+
}), {
|
|
810
|
+
applyMeasurementWrites: (writes) => {
|
|
811
|
+
setMeasurementsStore((draft) => {
|
|
812
|
+
for (let write of writes) if (write.hidden) {
|
|
813
|
+
let entry = draft[write.id];
|
|
814
|
+
entry && (entry.handleBounds = void 0);
|
|
815
|
+
} else draft[write.id] = {
|
|
816
|
+
measured: write.measured,
|
|
817
|
+
handleBounds: write.handleBounds
|
|
818
|
+
};
|
|
819
|
+
});
|
|
820
|
+
},
|
|
821
|
+
applyNodeChanges: (changes) => {
|
|
822
|
+
changes.length !== 0 && setNodesStore((nodes) => {
|
|
823
|
+
let nodeById = new Map(nodes.map((node) => [node.id, node]));
|
|
824
|
+
for (let change of changes) {
|
|
825
|
+
let node = nodeById.get(change.id);
|
|
826
|
+
if (node) switch (change.type) {
|
|
827
|
+
case "dimensions":
|
|
828
|
+
change.setAttributes && (node.width = change.dimensions?.width ?? node.width, node.height = change.dimensions?.height ?? node.height), node.measured = {
|
|
829
|
+
...node.measured,
|
|
830
|
+
...change.dimensions
|
|
831
|
+
};
|
|
832
|
+
break;
|
|
833
|
+
case "position": node.position = change.position ?? node.position;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
}), connectionKey = (nodeId, type, handleId) => `${nodeId}${type ? handleId ? `-${type}-${handleId}` : `-${type}` : ""}`, pairKey = (aNode, aHandle, bNode, bHandle) => `${aNode}-${aHandle}--${bNode}-${bHandle}`, createConnections = (source) => createProjection(() => {
|
|
560
839
|
let out = {}, add = (key, entry, connection) => {
|
|
561
840
|
(out[key] ??= {})[entry] = connection;
|
|
562
841
|
};
|
|
@@ -621,10 +900,6 @@ const EMPTY_AUTO_INDEX = /* @__PURE__ */ new Map(), createInternalNodes = (sourc
|
|
|
621
900
|
}, row.internals.z = z;
|
|
622
901
|
} else source.nodes.length;
|
|
623
902
|
}
|
|
624
|
-
if (userNode.parentId) {
|
|
625
|
-
let parent = entryById.get(userNode.parentId);
|
|
626
|
-
parent?.store.row.internals.positionAbsolute.x, parent?.store.row.internals.z;
|
|
627
|
-
}
|
|
628
903
|
return { row };
|
|
629
904
|
}, {}, { key: "id" }), entry = {
|
|
630
905
|
store,
|
|
@@ -693,8 +968,8 @@ const createLayoutedEdges = (source) => {
|
|
|
693
968
|
let rowStores = mapArray(() => source.edges, (edgeAccessor) => ({
|
|
694
969
|
id: edgeAccessor().id,
|
|
695
970
|
store: createProjection(() => {
|
|
696
|
-
let edge = edgeAccessor()
|
|
697
|
-
return
|
|
971
|
+
let edge = edgeAccessor();
|
|
972
|
+
return { row: buildRow(source, edge) };
|
|
698
973
|
}, { row: null }, { key: "id" })
|
|
699
974
|
}), { keyed: (edge) => edge.id }), assigned = /* @__PURE__ */ new Map();
|
|
700
975
|
return createProjection((draft) => {
|
|
@@ -710,7 +985,7 @@ const createLayoutedEdges = (source) => {
|
|
|
710
985
|
});
|
|
711
986
|
}, buildRow = (source, edge) => {
|
|
712
987
|
let sourceNode = source.nodeLookup.get(edge.source), targetNode = source.nodeLookup.get(edge.target);
|
|
713
|
-
if (!sourceNode || !targetNode) return
|
|
988
|
+
if (!sourceNode || !targetNode) return null;
|
|
714
989
|
let edgePosition = getEdgePosition({
|
|
715
990
|
id: edge.id,
|
|
716
991
|
sourceNode,
|
|
@@ -740,7 +1015,33 @@ const createLayoutedEdges = (source) => {
|
|
|
740
1015
|
let out = {};
|
|
741
1016
|
for (let node of source.nodes) node.parentId && (out[node.parentId] = !0);
|
|
742
1017
|
return out;
|
|
743
|
-
}, {}, { key: "id" }),
|
|
1018
|
+
}, {}, { key: "id" }), createSeededGraphStores = (props, config) => {
|
|
1019
|
+
props.nodes !== void 0 && props.defaultNodes, props.edges !== void 0 && props.defaultEdges;
|
|
1020
|
+
let [nodesStore, setNodesStore] = createStore(props.nodes ?? [...props.defaultNodes ?? []]), [edgesStore, setEdgesStore] = createStore(props.edges ?? [...props.defaultEdges ?? []]), nodeSeedAdopted = props.nodes !== void 0 || props.defaultNodes !== void 0, edgeSeedAdopted = props.edges !== void 0 || props.defaultEdges !== void 0;
|
|
1021
|
+
return createEffect(() => {
|
|
1022
|
+
let next = config().nodes;
|
|
1023
|
+
if (next) for (let node of next);
|
|
1024
|
+
return { next };
|
|
1025
|
+
}, ({ next }) => {
|
|
1026
|
+
next && (nodeSeedAdopted = !0, setNodesStore(() => next));
|
|
1027
|
+
}, { defer: !0 }), createEffect(() => {
|
|
1028
|
+
let next = config().edges;
|
|
1029
|
+
if (next) for (let edge of next);
|
|
1030
|
+
return { next };
|
|
1031
|
+
}, ({ next }) => {
|
|
1032
|
+
next && (edgeSeedAdopted = !0, setEdgesStore(() => next));
|
|
1033
|
+
}, { defer: !0 }), createEffect(() => ({
|
|
1034
|
+
nodes: config().defaultNodes,
|
|
1035
|
+
edges: config().defaultEdges
|
|
1036
|
+
}), ({ nodes: defaultNodes, edges: defaultEdges }) => {
|
|
1037
|
+
defaultNodes && !nodeSeedAdopted && config().nodes === void 0 && (nodeSeedAdopted = !0, setNodesStore(() => [...defaultNodes])), defaultEdges && !edgeSeedAdopted && config().edges === void 0 && (edgeSeedAdopted = !0, setEdgesStore(() => [...defaultEdges]));
|
|
1038
|
+
}, { defer: !0 }), {
|
|
1039
|
+
nodesStore,
|
|
1040
|
+
setNodesStore,
|
|
1041
|
+
edgesStore,
|
|
1042
|
+
setEdgesStore
|
|
1043
|
+
};
|
|
1044
|
+
}, getInitialViewport = (fitView, initialViewport, width, height, nodeLookup) => {
|
|
744
1045
|
if (fitView && !initialViewport && width && height) {
|
|
745
1046
|
let bounds = getInternalNodesBounds(nodeLookup, { filter: (node) => !!((node.width || node.initialWidth) && (node.height || node.initialHeight)) });
|
|
746
1047
|
return getViewportForBounds$1(bounds, width, height, .5, 2, .1);
|
|
@@ -751,9 +1052,7 @@ const createLayoutedEdges = (source) => {
|
|
|
751
1052
|
zoom: 1
|
|
752
1053
|
};
|
|
753
1054
|
}, createFlowState = (props, injections = {}) => {
|
|
754
|
-
let _props = merge(getDefaultFlowStateProps(), props), initialNodeTypes = injections.initialNodeTypes ?? {}, initialEdgeTypes = injections.initialEdgeTypes ?? {}, prefersDark = injections.prefersDark ?? (() => _props.colorModeSSR === "dark"), [config, setConfig] = createSignal(_props),
|
|
755
|
-
props.nodes !== void 0 && props.defaultNodes, props.edges !== void 0 && props.defaultEdges;
|
|
756
|
-
let [nodesStore, setNodesStore] = createStore(props.nodes ?? [...props.defaultNodes ?? []]), [edgesStore, setEdgesStore] = createStore(props.edges ?? [...props.defaultEdges ?? []]), nodeSeedAdopted = props.nodes !== void 0 || props.defaultNodes !== void 0, edgeSeedAdopted = props.edges !== void 0 || props.defaultEdges !== void 0, [measurementsStore, setMeasurementsStore] = createStore({}), internalNodes = createInternalNodes({
|
|
1055
|
+
let _props = merge(getDefaultFlowStateProps(), props), initialNodeTypes = injections.initialNodeTypes ?? {}, initialEdgeTypes = injections.initialEdgeTypes ?? {}, prefersDark = injections.prefersDark ?? (() => _props.colorModeSSR === "dark"), [config, setConfig] = createSignal(_props), ariaLabelConfig = createMemo(() => mergeAriaLabelConfig(config().ariaLabelConfig)), [ariaLiveMessage, setAriaLiveMessage] = createSignal(() => config().ariaLiveMessage), [clickConnectStartHandle, setClickConnectStartHandle] = createSignal(void 0), [connection, setConnection] = createSignal(initialConnection), [domNode, setDomNode] = createSignal(null), [dragging, setDragging] = createSignal(!1), [elementsSelectable, setElementsSelectable] = createSignal(() => config().elementsSelectable), [height, setHeight] = createSignal(() => config().height), minZoom = createMemo(() => config().minZoom), maxZoom = createMemo(() => config().maxZoom), [nodesConnectable, setNodesConnectable] = createSignal(() => config().nodesConnectable), [nodesDraggable, setNodesDraggable] = createSignal(() => config().nodesDraggable), [panZoom, setPanZoom] = createSignal(null), [selectionRect, setSelectionRect] = createSignal(), [selectionRectMode, setSelectionRectMode] = createSignal(), [snapGrid, setSnapGrid] = createSignal(() => config().snapGrid), translateExtent = createMemo(() => config().translateExtent ?? infiniteExtent), [width, setWidth] = createSignal(() => config().width), [selectionKeyPressed, setSelectionKeyPressed] = createSignal(!1), [multiselectionKeyPressed, setMultiselectionKeyPressed] = createSignal(!1), [deleteKeyPressed, setDeleteKeyPressed] = createSignal(!1), [panActivationKeyPressed, setPanActivationKeyPressed] = createSignal(!1), [zoomActivationKeyPressed, setZoomActivationKeyPressed] = createSignal(!1), { nodesStore, setNodesStore, edgesStore, setEdgesStore } = createSeededGraphStores(props, config), [measurementsStore, setMeasurementsStore] = createStore({}), internalNodes = createInternalNodes({
|
|
757
1056
|
get nodes() {
|
|
758
1057
|
return nodesStore;
|
|
759
1058
|
},
|
|
@@ -773,24 +1072,7 @@ const createLayoutedEdges = (source) => {
|
|
|
773
1072
|
return config().zIndexMode;
|
|
774
1073
|
}
|
|
775
1074
|
}), nodeLookup = new RecordMapFacade(internalNodes), initialViewport = getInitialViewport(_props.fitView, _props.initialViewport, _props.width ?? 0, _props.height ?? 0, nodeLookup), [viewportStore, setViewportStore] = createStore(_props.viewport ?? initialViewport);
|
|
776
|
-
createEffect(() => {
|
|
777
|
-
let next = config().nodes;
|
|
778
|
-
if (next) for (let node of next);
|
|
779
|
-
return { next };
|
|
780
|
-
}, ({ next }) => {
|
|
781
|
-
next && (nodeSeedAdopted = !0, setNodesStore(() => next));
|
|
782
|
-
}, { defer: !0 }), createEffect(() => {
|
|
783
|
-
let next = config().edges;
|
|
784
|
-
if (next) for (let edge of next);
|
|
785
|
-
return { next };
|
|
786
|
-
}, ({ next }) => {
|
|
787
|
-
next && (edgeSeedAdopted = !0, setEdgesStore(() => next));
|
|
788
|
-
}, { defer: !0 }), createEffect(() => ({
|
|
789
|
-
nodes: config().defaultNodes,
|
|
790
|
-
edges: config().defaultEdges
|
|
791
|
-
}), ({ nodes: defaultNodes, edges: defaultEdges }) => {
|
|
792
|
-
defaultNodes && !nodeSeedAdopted && config().nodes === void 0 && (nodeSeedAdopted = !0, setNodesStore(() => [...defaultNodes])), defaultEdges && !edgeSeedAdopted && config().edges === void 0 && (edgeSeedAdopted = !0, setEdgesStore(() => [...defaultEdges]));
|
|
793
|
-
}, { defer: !0 }), createEffect(() => config().viewport, (next) => {
|
|
1075
|
+
createEffect(() => config().viewport, (next) => {
|
|
794
1076
|
next && setViewportStore(() => next);
|
|
795
1077
|
}, { defer: !0 });
|
|
796
1078
|
let transform = createMemo(() => [
|
|
@@ -802,25 +1084,29 @@ const createLayoutedEdges = (source) => {
|
|
|
802
1084
|
if (nodes.length === 0) return !1;
|
|
803
1085
|
for (let node of nodes) if (!node.hidden && (node.measured?.width === void 0 || node.measured?.height === void 0)) return !1;
|
|
804
1086
|
return !0;
|
|
805
|
-
}),
|
|
1087
|
+
}), resolvedColorMode = createMemo(() => {
|
|
1088
|
+
let mode = config().colorMode;
|
|
1089
|
+
return mode === "system" ? prefersDark() ? "dark" : "light" : mode;
|
|
1090
|
+
}), projectedConnection = createMemo(() => {
|
|
1091
|
+
let state = connection();
|
|
1092
|
+
return state.inProgress ? {
|
|
1093
|
+
...state,
|
|
1094
|
+
to: pointToRendererPoint(state.to, transform())
|
|
1095
|
+
} : state;
|
|
1096
|
+
}), connectionFromHandle = createMemo(() => connection().fromHandle ?? null, { equals: (a, b) => a === b || !!a && !!b && a.nodeId === b.nodeId && a.type === b.type && a.id === b.id }), connectionTargetByHandle = createProjection((draft) => {
|
|
1097
|
+
let state = connection(), toHandle = state.inProgress ? state.toHandle : null, key = toHandle ? connectionKey(toHandle.nodeId, toHandle.type, toHandle.id ?? null) : null;
|
|
1098
|
+
for (let existing of Object.keys(draft)) existing !== key && delete draft[existing];
|
|
1099
|
+
key && (draft[key] = state.isValid ? "valid" : "invalid");
|
|
1100
|
+
}, {}, { key: null }), mergedNodeTypes = createMemo(() => ({
|
|
1101
|
+
...initialNodeTypes,
|
|
1102
|
+
...config().nodeTypes
|
|
1103
|
+
})), mergedEdgeTypes = createMemo(() => ({
|
|
1104
|
+
...initialEdgeTypes,
|
|
1105
|
+
...config().edgeTypes
|
|
1106
|
+
})), selectedNodesView = createMemo(() => nodesStore.filter((node) => node.selected)), selectedEdgesView = createMemo(() => edgesStore.filter((edge) => edge.selected)), store = merge({
|
|
806
1107
|
width: 0,
|
|
807
1108
|
height: 0
|
|
808
1109
|
}, config, {
|
|
809
|
-
get _colorMode() {
|
|
810
|
-
return config().colorMode;
|
|
811
|
-
},
|
|
812
|
-
get _colorModeSSR() {
|
|
813
|
-
return config().colorModeSSR;
|
|
814
|
-
},
|
|
815
|
-
get _connection() {
|
|
816
|
-
return connection();
|
|
817
|
-
},
|
|
818
|
-
get _nodeTypes() {
|
|
819
|
-
return config().nodeTypes;
|
|
820
|
-
},
|
|
821
|
-
get _edgeTypes() {
|
|
822
|
-
return config().edgeTypes;
|
|
823
|
-
},
|
|
824
1110
|
get ariaLabelConfig() {
|
|
825
1111
|
return ariaLabelConfig();
|
|
826
1112
|
},
|
|
@@ -831,14 +1117,16 @@ const createLayoutedEdges = (source) => {
|
|
|
831
1117
|
return clickConnectStartHandle();
|
|
832
1118
|
},
|
|
833
1119
|
get colorMode() {
|
|
834
|
-
return
|
|
1120
|
+
return resolvedColorMode();
|
|
835
1121
|
},
|
|
836
1122
|
get connection() {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
1123
|
+
return projectedConnection();
|
|
1124
|
+
},
|
|
1125
|
+
get connectionFromHandle() {
|
|
1126
|
+
return connectionFromHandle();
|
|
1127
|
+
},
|
|
1128
|
+
get connectionTargetByHandle() {
|
|
1129
|
+
return connectionTargetByHandle;
|
|
842
1130
|
},
|
|
843
1131
|
get domNode() {
|
|
844
1132
|
return domNode();
|
|
@@ -847,10 +1135,7 @@ const createLayoutedEdges = (source) => {
|
|
|
847
1135
|
return dragging();
|
|
848
1136
|
},
|
|
849
1137
|
get edgeTypes() {
|
|
850
|
-
return
|
|
851
|
-
...initialEdgeTypes,
|
|
852
|
-
...this._edgeTypes
|
|
853
|
-
};
|
|
1138
|
+
return mergedEdgeTypes();
|
|
854
1139
|
},
|
|
855
1140
|
get elementsSelectable() {
|
|
856
1141
|
return elementsSelectable();
|
|
@@ -883,19 +1168,16 @@ const createLayoutedEdges = (source) => {
|
|
|
883
1168
|
return nodesDraggable();
|
|
884
1169
|
},
|
|
885
1170
|
get nodeTypes() {
|
|
886
|
-
return
|
|
887
|
-
...initialNodeTypes,
|
|
888
|
-
...this._nodeTypes
|
|
889
|
-
};
|
|
1171
|
+
return mergedNodeTypes();
|
|
890
1172
|
},
|
|
891
1173
|
get panZoom() {
|
|
892
1174
|
return panZoom();
|
|
893
1175
|
},
|
|
894
1176
|
get selectedNodes() {
|
|
895
|
-
return
|
|
1177
|
+
return selectedNodesView();
|
|
896
1178
|
},
|
|
897
1179
|
get selectedEdges() {
|
|
898
|
-
return
|
|
1180
|
+
return selectedEdgesView();
|
|
899
1181
|
},
|
|
900
1182
|
get selectionRect() {
|
|
901
1183
|
return selectionRect();
|
|
@@ -1010,33 +1292,11 @@ const createLayoutedEdges = (source) => {
|
|
|
1010
1292
|
setNodesStore((nodes) => {
|
|
1011
1293
|
for (let node of nodes) nodeDragItems.has(node.id) && (node.dragging = dragging, node.position = nodeDragItems.get(node.id).position);
|
|
1012
1294
|
});
|
|
1013
|
-
}, applyMeasurementWrites = (
|
|
1014
|
-
setMeasurementsStore
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
} else draft[write.id] = {
|
|
1019
|
-
measured: write.measured,
|
|
1020
|
-
handleBounds: write.handleBounds
|
|
1021
|
-
};
|
|
1022
|
-
});
|
|
1023
|
-
}, applyNodeChanges = (changes) => {
|
|
1024
|
-
changes.length !== 0 && setNodesStore((nodes) => {
|
|
1025
|
-
let nodeById = new Map(nodes.map((node) => [node.id, node]));
|
|
1026
|
-
for (let change of changes) {
|
|
1027
|
-
let node = nodeById.get(change.id);
|
|
1028
|
-
if (node) switch (change.type) {
|
|
1029
|
-
case "dimensions":
|
|
1030
|
-
change.setAttributes && (node.width = change.dimensions?.width ?? node.width, node.height = change.dimensions?.height ?? node.height), node.measured = {
|
|
1031
|
-
...node.measured,
|
|
1032
|
-
...change.dimensions
|
|
1033
|
-
};
|
|
1034
|
-
break;
|
|
1035
|
-
case "position": node.position = change.position ?? node.position;
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
});
|
|
1039
|
-
}, markInitialNodesMeasured = () => {
|
|
1295
|
+
}, { applyMeasurementWrites, applyNodeChanges } = createMeasurementIngest({
|
|
1296
|
+
setMeasurementsStore,
|
|
1297
|
+
setNodesStore,
|
|
1298
|
+
nodes: () => nodesStore
|
|
1299
|
+
}), markInitialNodesMeasured = () => {
|
|
1040
1300
|
initialNodesMeasured = !0, tryInitialFitView();
|
|
1041
1301
|
}, requestMeasure = () => {}, setMeasureRequester = (fn) => {
|
|
1042
1302
|
requestMeasure = fn;
|
|
@@ -1051,66 +1311,16 @@ const createLayoutedEdges = (source) => {
|
|
|
1051
1311
|
ease: options?.ease,
|
|
1052
1312
|
interpolate: options?.interpolate
|
|
1053
1313
|
}), Promise.resolve(!0)) : Promise.resolve(!1);
|
|
1054
|
-
},
|
|
1055
|
-
store
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
}), flush();
|
|
1065
|
-
}, addSelectedNodes = (ids) => {
|
|
1066
|
-
let isMultiSelection = store.multiselectionKeyPressed;
|
|
1067
|
-
setNodesStore((nodes) => {
|
|
1068
|
-
for (let node of nodes) {
|
|
1069
|
-
let nodeWillBeSelected = ids.includes(node.id), selected = isMultiSelection && node.selected || nodeWillBeSelected;
|
|
1070
|
-
node.selected !== selected && (node.selected = selected);
|
|
1071
|
-
}
|
|
1072
|
-
}), isMultiSelection || unselectNodesAndEdges({ nodes: [] }), flush();
|
|
1073
|
-
}, addSelectedEdges = (ids) => {
|
|
1074
|
-
let isMultiSelection = store.multiselectionKeyPressed;
|
|
1075
|
-
setEdgesStore((edges) => {
|
|
1076
|
-
for (let edge of edges) {
|
|
1077
|
-
let edgeWillBeSelected = ids.includes(edge.id), selected = isMultiSelection && edge.selected || edgeWillBeSelected;
|
|
1078
|
-
edge.selected !== selected && (edge.selected = selected);
|
|
1079
|
-
}
|
|
1080
|
-
}), isMultiSelection || unselectNodesAndEdges({ edges: [] }), flush();
|
|
1081
|
-
}, handleNodeSelection = (id, unselect, nodeRef) => {
|
|
1082
|
-
let node = store.nodes.find((n) => n.id === id);
|
|
1083
|
-
node && (setSelectionRect(void 0), setSelectionRectMode(void 0), node.selected ? (unselect || node.selected && store.multiselectionKeyPressed) && (unselectNodesAndEdges({
|
|
1084
|
-
nodes: [node],
|
|
1085
|
-
edges: []
|
|
1086
|
-
}), requestAnimationFrame(() => nodeRef?.blur())) : addSelectedNodes([id]));
|
|
1087
|
-
}, handleEdgeSelection = (id) => {
|
|
1088
|
-
let edge = edgeLookup[id];
|
|
1089
|
-
edge && (edge.selectable || store.elementsSelectable && edge.selectable === void 0) && (setSelectionRect(void 0), setSelectionRectMode(void 0), edge.selected ? edge.selected && store.multiselectionKeyPressed && unselectNodesAndEdges({
|
|
1090
|
-
nodes: [],
|
|
1091
|
-
edges: [edge]
|
|
1092
|
-
}) : addSelectedEdges([id]));
|
|
1093
|
-
}, moveSelectedNodes = (direction, factor) => {
|
|
1094
|
-
let nodeUpdates = /* @__PURE__ */ new Map(), xVelo = store.snapGrid?.[0] ?? 5, yVelo = store.snapGrid?.[1] ?? 5, xDiff = direction.x * xVelo * factor, yDiff = direction.y * yVelo * factor;
|
|
1095
|
-
for (let node of nodeLookup.values()) {
|
|
1096
|
-
if (!(node.selected && (node.draggable || store.nodesDraggable && node.draggable === void 0))) continue;
|
|
1097
|
-
let nextPosition = {
|
|
1098
|
-
x: node.internals.positionAbsolute.x + xDiff,
|
|
1099
|
-
y: node.internals.positionAbsolute.y + yDiff
|
|
1100
|
-
};
|
|
1101
|
-
store.snapGrid && (nextPosition = snapPosition(nextPosition, store.snapGrid));
|
|
1102
|
-
let { position } = calculateNodePosition({
|
|
1103
|
-
nodeId: node.id,
|
|
1104
|
-
nextPosition,
|
|
1105
|
-
nodeLookup,
|
|
1106
|
-
nodeExtent: store.nodeExtent,
|
|
1107
|
-
nodeOrigin: store.nodeOrigin,
|
|
1108
|
-
onError: store.onError
|
|
1109
|
-
});
|
|
1110
|
-
nodeUpdates.set(node.id, { position });
|
|
1111
|
-
}
|
|
1112
|
-
updateNodePositions(nodeUpdates);
|
|
1113
|
-
}, panBy$1 = (delta) => panBy({
|
|
1314
|
+
}, stableSetViewport = (viewport) => setViewportStore(() => viewport), { unselectNodesAndEdges, addSelectedNodes, addSelectedEdges, handleNodeSelection, handleEdgeSelection, moveSelectedNodes } = createSelectionCommands({
|
|
1315
|
+
store,
|
|
1316
|
+
setNodesStore,
|
|
1317
|
+
setEdgesStore,
|
|
1318
|
+
setSelectionRect,
|
|
1319
|
+
setSelectionRectMode,
|
|
1320
|
+
nodeLookup,
|
|
1321
|
+
edgeLookup,
|
|
1322
|
+
updateNodePositions
|
|
1323
|
+
}), panBy$1 = (delta) => panBy({
|
|
1114
1324
|
delta,
|
|
1115
1325
|
panZoom: store.panZoom,
|
|
1116
1326
|
transform: store.transform,
|
|
@@ -1187,8 +1397,27 @@ const createLayoutedEdges = (source) => {
|
|
|
1187
1397
|
get snapGrid() {
|
|
1188
1398
|
return store.snapGrid;
|
|
1189
1399
|
}
|
|
1190
|
-
},
|
|
1191
|
-
|
|
1400
|
+
}, intersectionGrid = null, intersectionRows = null, queryIntersectionCandidates = (rect) => untrack(() => {
|
|
1401
|
+
if (!intersectionGrid) {
|
|
1402
|
+
let grid = new SpatialGrid(300), rows = /* @__PURE__ */ new Map();
|
|
1403
|
+
for (let node of store.nodes) {
|
|
1404
|
+
let internalNode = nodeLookup.get(node.id);
|
|
1405
|
+
internalNode && (grid.insert(node.id, nodeToRect(internalNode)), rows.set(node.id, node));
|
|
1406
|
+
}
|
|
1407
|
+
intersectionGrid = grid, intersectionRows = rows, queueMicrotask(() => {
|
|
1408
|
+
intersectionGrid = null, intersectionRows = null;
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
let rows = intersectionRows, result = [];
|
|
1412
|
+
for (let id of intersectionGrid.queryRect(rect)) {
|
|
1413
|
+
let row = rows.get(id);
|
|
1414
|
+
row && result.push(row);
|
|
1415
|
+
}
|
|
1416
|
+
return result;
|
|
1417
|
+
}), getNodeRect = (node) => {
|
|
1418
|
+
let nodeToUse = isNode(node) ? node : nodeLookup.get(node.id);
|
|
1419
|
+
if (!nodeToUse) return null;
|
|
1420
|
+
let position = nodeToUse.parentId ? evaluateAbsolutePosition(nodeToUse.position, nodeToUse.measured, nodeToUse.parentId, nodeLookup, store.nodeOrigin) : nodeToUse.position, nodeWithPosition = {
|
|
1192
1421
|
...nodeToUse,
|
|
1193
1422
|
position,
|
|
1194
1423
|
width: nodeToUse.measured?.width ?? nodeToUse.width,
|
|
@@ -1242,7 +1471,7 @@ const createLayoutedEdges = (source) => {
|
|
|
1242
1471
|
x,
|
|
1243
1472
|
y,
|
|
1244
1473
|
zoom
|
|
1245
|
-
], _snapGrid
|
|
1474
|
+
], !!_snapGrid, _snapGrid || [1, 1]);
|
|
1246
1475
|
},
|
|
1247
1476
|
flowToScreenPosition: (position) => {
|
|
1248
1477
|
if (!store.domNode) return position;
|
|
@@ -1306,14 +1535,18 @@ const createLayoutedEdges = (source) => {
|
|
|
1306
1535
|
let remainingNodes = store.nodes.filter((node) => !matchingNodes.some(({ id }) => id === node.id));
|
|
1307
1536
|
store.onNodesDelete?.(matchingNodes), setNodesStore(() => remainingNodes);
|
|
1308
1537
|
}
|
|
1309
|
-
|
|
1538
|
+
let deletedNodes = matchingNodes ?? [], deletedEdges = matchingEdges ?? [];
|
|
1539
|
+
return (deletedNodes.length > 0 || deletedEdges.length > 0) && store.onDelete?.({
|
|
1540
|
+
nodes: deletedNodes,
|
|
1541
|
+
edges: deletedEdges
|
|
1542
|
+
}), {
|
|
1310
1543
|
deletedNodes: matchingNodes,
|
|
1311
1544
|
deletedEdges: matchingEdges
|
|
1312
1545
|
};
|
|
1313
1546
|
},
|
|
1314
1547
|
getIntersectingNodes: (nodeOrRect, partially = !0, nodesToIntersect) => {
|
|
1315
1548
|
let isRect = isRectObject(nodeOrRect), nodeRect = isRect ? nodeOrRect : getNodeRect(nodeOrRect);
|
|
1316
|
-
return nodeRect ? (nodesToIntersect
|
|
1549
|
+
return nodeRect ? (nodesToIntersect ?? queryIntersectionCandidates(nodeRect)).filter((n) => {
|
|
1317
1550
|
let internalNode = nodeLookup.get(n.id);
|
|
1318
1551
|
if (!internalNode || !isRect && n.id === nodeOrRect.id) return !1;
|
|
1319
1552
|
let currNodeRect = nodeToRect(internalNode), overlappingArea = getOverlappingArea(currNodeRect, nodeRect);
|
|
@@ -1369,10 +1602,6 @@ const createLayoutedEdges = (source) => {
|
|
|
1369
1602
|
extent: store.translateExtent
|
|
1370
1603
|
}), ({ panZoom, extent }) => {
|
|
1371
1604
|
panZoom?.setTranslateExtent(extent);
|
|
1372
|
-
}), createEffect(() => new Set(store.nodes.map((n) => n.id)), (currentIds) => {
|
|
1373
|
-
setMeasurementsStore((draft) => {
|
|
1374
|
-
for (let id of Object.keys(draft)) currentIds.has(id) || delete draft[id];
|
|
1375
|
-
});
|
|
1376
1605
|
}), {
|
|
1377
1606
|
store,
|
|
1378
1607
|
flow,
|
|
@@ -1390,8 +1619,6 @@ const createLayoutedEdges = (source) => {
|
|
|
1390
1619
|
applyNodeChanges,
|
|
1391
1620
|
markInitialNodesMeasured,
|
|
1392
1621
|
setMeasureRequester,
|
|
1393
|
-
resetStoreValues,
|
|
1394
|
-
setAriaLabelConfig,
|
|
1395
1622
|
setAriaLiveMessage,
|
|
1396
1623
|
setClickConnectStartHandle,
|
|
1397
1624
|
setConfig,
|
|
@@ -1399,15 +1626,11 @@ const createLayoutedEdges = (source) => {
|
|
|
1399
1626
|
setDeleteKeyPressed,
|
|
1400
1627
|
setDomNode,
|
|
1401
1628
|
setDragging,
|
|
1402
|
-
|
|
1403
|
-
return setEdgesStore;
|
|
1404
|
-
},
|
|
1629
|
+
setEdges: setEdgesStore,
|
|
1405
1630
|
setElementsSelectable,
|
|
1406
1631
|
setHeight,
|
|
1407
1632
|
setMultiselectionKeyPressed,
|
|
1408
|
-
|
|
1409
|
-
return setNodesStore;
|
|
1410
|
-
},
|
|
1633
|
+
setNodes: setNodesStore,
|
|
1411
1634
|
setNodesConnectable,
|
|
1412
1635
|
setNodesDraggable,
|
|
1413
1636
|
setPanActivationKeyPressed,
|
|
@@ -1415,9 +1638,7 @@ const createLayoutedEdges = (source) => {
|
|
|
1415
1638
|
setSelectionKeyPressed,
|
|
1416
1639
|
setSelectionRect,
|
|
1417
1640
|
setSelectionRectMode,
|
|
1418
|
-
|
|
1419
|
-
return (viewport) => setViewportStore(() => viewport);
|
|
1420
|
-
},
|
|
1641
|
+
setViewport: stableSetViewport,
|
|
1421
1642
|
setWidth,
|
|
1422
1643
|
setZoomActivationKeyPressed,
|
|
1423
1644
|
addEdge,
|
|
@@ -1426,7 +1647,6 @@ const createLayoutedEdges = (source) => {
|
|
|
1426
1647
|
zoomOut,
|
|
1427
1648
|
fitView,
|
|
1428
1649
|
setCenter,
|
|
1429
|
-
setPaneClickDistance,
|
|
1430
1650
|
unselectNodesAndEdges,
|
|
1431
1651
|
addSelectedNodes,
|
|
1432
1652
|
addSelectedEdges,
|
|
@@ -1438,8 +1658,11 @@ const createLayoutedEdges = (source) => {
|
|
|
1438
1658
|
reset
|
|
1439
1659
|
}
|
|
1440
1660
|
};
|
|
1661
|
+
}, createEdgeStore = (edges) => {
|
|
1662
|
+
let [store, setStore] = typeof edges == "function" ? createStore(edges, []) : createStore(edges);
|
|
1663
|
+
return [store, setStore];
|
|
1441
1664
|
}, createNodeStore = (nodes) => {
|
|
1442
|
-
let [store, setStore] = createStore(nodes);
|
|
1665
|
+
let [store, setStore] = typeof nodes == "function" ? createStore(nodes, []) : createStore(nodes);
|
|
1443
1666
|
return [store, setStore];
|
|
1444
1667
|
};
|
|
1445
1668
|
//#endregion
|
|
@@ -1447,21 +1670,21 @@ const createLayoutedEdges = (source) => {
|
|
|
1447
1670
|
var _tmpl$$30 = /* @__PURE__ */ template("<svg class=solid-flow__edge-wrapper><g>");
|
|
1448
1671
|
/** Internal per-edge wrapper: interaction, a11y, viewport culling, and the dynamic edge component. */
|
|
1449
1672
|
const EdgeWrapper = (props) => {
|
|
1450
|
-
let edgeRef, { store, actions } = useInternalSolidFlow(), edgeId = () => props.edgeId, edge = () => actions.getEdge(edgeId()), edgeType = () => edge().type ?? "default", selectable = () => edge()
|
|
1673
|
+
let edgeRef, { store, actions } = useInternalSolidFlow(), edgeId = () => props.edgeId, edge = () => actions.getEdge(edgeId()), edgeType = () => edge().type ?? "default", selectable = () => isEdgeSelectable(edge(), store), focusable = () => edge().focusable ?? store.edgesFocusable, edgeComponent = () => store.edgeTypes[edgeType()], markerStartUrl = () => edge().markerStart ? `url('#${getMarkerId(edge().markerStart, store.id)}')` : void 0, markerEndUrl = () => edge().markerEnd ? `url('#${getMarkerId(edge().markerEnd, store.id)}')` : void 0, onClick = (event) => {
|
|
1451
1674
|
selectable() && actions.handleEdgeSelection(edgeId()), props.onEdgeClick?.({
|
|
1452
1675
|
edge: edge(),
|
|
1453
1676
|
event
|
|
1454
1677
|
});
|
|
1455
|
-
},
|
|
1456
|
-
(
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
}, onKeyDown = (event) => {
|
|
1678
|
+
}, onContextMenu = (event) => props.onEdgeContextMenu?.({
|
|
1679
|
+
edge: edge(),
|
|
1680
|
+
event
|
|
1681
|
+
}), onPointerEnter = (event) => props.onEdgePointerEnter?.({
|
|
1682
|
+
edge: edge(),
|
|
1683
|
+
event
|
|
1684
|
+
}), onPointerLeave = (event) => props.onEdgePointerLeave?.({
|
|
1685
|
+
edge: edge(),
|
|
1686
|
+
event
|
|
1687
|
+
}), onKeyDown = (event) => {
|
|
1465
1688
|
store.disableKeyboardA11y || !elementSelectionKeys.includes(event.key) || !selectable() || (event.key === "Escape" ? (edgeRef?.blur(), actions.unselectNodesAndEdges({ edges: [edge()] })) : actions.addSelectedEdges([edge().id]));
|
|
1466
1689
|
}, ariaLabel = () => edge().ariaLabel ?? `Edge from ${edge().source} to ${edge().target}`, culled = createMemo(() => isEdgeCulled(edge(), store.cullingViewport));
|
|
1467
1690
|
return createComponent(EdgeIdContext, {
|
|
@@ -1504,9 +1727,9 @@ const EdgeWrapper = (props) => {
|
|
|
1504
1727
|
},
|
|
1505
1728
|
onClick,
|
|
1506
1729
|
onKeyDown: (e) => focusable() && onKeyDown(e),
|
|
1507
|
-
onContextMenu
|
|
1508
|
-
onPointerEnter
|
|
1509
|
-
onPointerLeave
|
|
1730
|
+
onContextMenu,
|
|
1731
|
+
onPointerEnter,
|
|
1732
|
+
onPointerLeave
|
|
1510
1733
|
}, () => edge().domAttributes), !0), insert(_el$2, createComponent(Dynamic, {
|
|
1511
1734
|
get component() {
|
|
1512
1735
|
return edgeComponent();
|
|
@@ -1887,7 +2110,10 @@ const Handle = (props) => {
|
|
|
1887
2110
|
position: "top",
|
|
1888
2111
|
isConnectableStart: !0,
|
|
1889
2112
|
isConnectableEnd: !0
|
|
1890
|
-
}), { 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, connectionInProcess = () => !!store.
|
|
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, connectionInProcess = () => !!store.connectionFromHandle, connectingFrom = () => {
|
|
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;
|
|
1891
2117
|
createEffect(() => {
|
|
1892
2118
|
if (!_props.onConnect && !_props.onDisconnect) return null;
|
|
1893
2119
|
let rec = connections[connectionKey(nodeId(), _props.type, _props.id)], map = /* @__PURE__ */ new Map();
|
|
@@ -1905,13 +2131,20 @@ const Handle = (props) => {
|
|
|
1905
2131
|
}, edge = store.onBeforeConnect?.(handleConnection) ?? handleConnection;
|
|
1906
2132
|
actions.addEdge(edge), store.onConnect?.(handleConnection);
|
|
1907
2133
|
}, onPointerDown = (event) => {
|
|
2134
|
+
let gestureLookup = armConnectionGestureLookup({
|
|
2135
|
+
event,
|
|
2136
|
+
real: nodeLookup,
|
|
2137
|
+
domNode: store.domNode,
|
|
2138
|
+
getTransform: () => store.transform,
|
|
2139
|
+
connectionRadius: store.connectionRadius
|
|
2140
|
+
});
|
|
1908
2141
|
XYHandle.onPointerDown(event, {
|
|
1909
2142
|
handleId: handleId(),
|
|
1910
2143
|
nodeId: nodeId(),
|
|
1911
2144
|
isTarget: isTarget(),
|
|
1912
2145
|
connectionRadius: store.connectionRadius,
|
|
1913
2146
|
domNode: store.domNode,
|
|
1914
|
-
nodeLookup,
|
|
2147
|
+
nodeLookup: gestureLookup,
|
|
1915
2148
|
connectionMode: store.connectionMode,
|
|
1916
2149
|
lib: store.lib,
|
|
1917
2150
|
autoPanOnConnect: store.autoPanOnConnect,
|
|
@@ -2152,12 +2385,11 @@ const NodeWrapper = (props) => {
|
|
|
2152
2385
|
...h ? { height: toPxString(h) } : {}
|
|
2153
2386
|
};
|
|
2154
2387
|
}, culled = createMemo(() => isNodeCulled(node(), store.cullingViewport)), style = () => ({
|
|
2388
|
+
...sizeStyle(),
|
|
2155
2389
|
"z-index": node().internals.z,
|
|
2156
2390
|
transform: transform(),
|
|
2157
2391
|
visibility: culled() || !nodeHasDimensions(node()) ? "hidden" : "visible",
|
|
2158
|
-
"pointer-events": culled() ? "none" : void 0
|
|
2159
|
-
...sizeStyle(),
|
|
2160
|
-
...node().style ?? {}
|
|
2392
|
+
"pointer-events": culled() ? "none" : void 0
|
|
2161
2393
|
});
|
|
2162
2394
|
createEffect(() => ({
|
|
2163
2395
|
valid: nodeTypeValid(),
|
|
@@ -2517,7 +2749,7 @@ const InitialNodeTypesMap = {
|
|
|
2517
2749
|
pendingEntries = updateEntries, scheduleIdleCallback(() => {
|
|
2518
2750
|
let updates = new Map(pendingEntries);
|
|
2519
2751
|
pendingEntries = void 0;
|
|
2520
|
-
let { updatedInternals, measurementWrites, changes, parentExpandChildren } = measureNodeInternals(updates, nodeLookup, store.domNode);
|
|
2752
|
+
let { updatedInternals, measurementWrites, changes, parentExpandChildren } = measureNodeInternals(updates, nodeLookup, store.domNode, store.nodeExtent);
|
|
2521
2753
|
updatedInternals && (actions.applyMeasurementWrites(measurementWrites), flush(), parentExpandChildren.length > 0 && changes.push(...handleExpandParent(parentExpandChildren, nodeLookup, (parentId) => store.nodes.filter((node) => node.parentId === parentId), store.nodeOrigin)), actions.applyNodeChanges(changes), flush(), actions.markInitialNodesMeasured());
|
|
2522
2754
|
});
|
|
2523
2755
|
};
|
|
@@ -2848,7 +3080,7 @@ const isSetEqual = (a, b) => {
|
|
|
2848
3080
|
for (let item of a) if (!b.has(item)) return !1;
|
|
2849
3081
|
return !0;
|
|
2850
3082
|
}, Pane = (props) => {
|
|
2851
|
-
let { store, nodeLookup, edgeLookup, connections, actions } = useInternalSolidFlow(), [containerRef, setContainerRef] = createSignal(), container, containerBounds = null, connectionEndedOnPane = !1, selectionInProgress = !1, selectedNodeIds = /* @__PURE__ */ new Set(), selectedEdgeIds = /* @__PURE__ */ new Set(), autoPanId = 0, position = {
|
|
3083
|
+
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 = {
|
|
2852
3084
|
x: 0,
|
|
2853
3085
|
y: 0
|
|
2854
3086
|
}, autoPanStarted = !1, autoPanOnSelection = () => props.autoPanOnSelection ?? !0, paneClickDistance = () => props.paneClickDistance ?? 1, _panOnDrag = () => store.panActivationKeyPressed || props.panOnDrag, isSelecting = () => store.selectionKeyPressed || !!store.selectionRect || props.selectionOnDrag && _panOnDrag() !== !0, isSelectionEnabled = () => store.elementsSelectable && (isSelecting() || store.selectionRectMode === "user"), onClick = (event) => {
|
|
@@ -2863,7 +3095,7 @@ const isSetEqual = (a, b) => {
|
|
|
2863
3095
|
if (event.pointerType === "touch" && _panOnDrag() !== !1 && !store.selectionKeyPressed || (containerBounds = container?.getBoundingClientRect() ?? null, !containerBounds)) return;
|
|
2864
3096
|
let eventTargetIsContainer = event.target === container, isNoKeyEvent = !eventTargetIsContainer && !!event.target.closest(".nokey"), isSelectionActive = props.selectionOnDrag && eventTargetIsContainer || store.selectionKeyPressed;
|
|
2865
3097
|
if (isNoKeyEvent || !isSelecting() || !isSelectionActive || event.button !== 0 || !event.isPrimary) return;
|
|
2866
|
-
event.target?.setPointerCapture?.(event.pointerId), selectionInProgress = !1, autoPanStarted = !1;
|
|
3098
|
+
event.target?.setPointerCapture?.(event.pointerId), selectionSpatialLookup.arm((node) => nodeToRect(node)), selectionInProgress = !1, autoPanStarted = !1;
|
|
2867
3099
|
let { x, y } = getEventPosition(event, containerBounds), userSelectionFlowOrigin = pointToRendererPoint({
|
|
2868
3100
|
x,
|
|
2869
3101
|
y
|
|
@@ -2890,14 +3122,21 @@ const isSetEqual = (a, b) => {
|
|
|
2890
3122
|
width: Math.abs(mouseX - screenStart.x),
|
|
2891
3123
|
height: Math.abs(mouseY - screenStart.y)
|
|
2892
3124
|
}, prevSelectedNodeIds = selectedNodeIds, prevSelectedEdgeIds = selectedEdgeIds;
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
3125
|
+
{
|
|
3126
|
+
let [tx, ty, zoom] = store.transform;
|
|
3127
|
+
selectionSpatialLookup.setQueryRect({
|
|
3128
|
+
x: (nextUserSelectRect.x - tx) / zoom,
|
|
3129
|
+
y: (nextUserSelectRect.y - ty) / zoom,
|
|
3130
|
+
width: nextUserSelectRect.width / zoom,
|
|
3131
|
+
height: nextUserSelectRect.height / zoom
|
|
3132
|
+
});
|
|
3133
|
+
}
|
|
3134
|
+
selectedNodeIds = new Set(getNodesInside(selectionSpatialLookup, nextUserSelectRect, store.transform, store.selectionMode === SelectionMode$1.Partial, !0).map((n) => n.id)), selectedEdgeIds = /* @__PURE__ */ new Set();
|
|
2896
3135
|
for (let nodeId of selectedNodeIds) {
|
|
2897
3136
|
let nodeConnections = connections[nodeId];
|
|
2898
3137
|
if (nodeConnections) for (let { edgeId } of Object.values(nodeConnections)) {
|
|
2899
3138
|
let edge = edgeLookup[edgeId];
|
|
2900
|
-
edge && (edge
|
|
3139
|
+
edge && isEdgeSelectable(edge, store) && selectedEdgeIds.add(edgeId);
|
|
2901
3140
|
}
|
|
2902
3141
|
}
|
|
2903
3142
|
isSetEqual(prevSelectedNodeIds, selectedNodeIds) || actions.setNodes((nodes) => {
|
|
@@ -3132,7 +3371,7 @@ const Selection = (props) => {
|
|
|
3132
3371
|
var _tmpl$$16 = /* @__PURE__ */ template("<div>");
|
|
3133
3372
|
/** Internal draggable bounding box rendered around multi-selected nodes. */
|
|
3134
3373
|
const NodeSelection = (props) => {
|
|
3135
|
-
let { store, nodeLookup, actions } = useInternalSolidFlow(), [ref$2, setRef] = createSignal(), bounds = () => store.selectionRectMode === "nodes" ? getInternalNodesBounds(nodeLookup, { filter: (node) => !!node.selected }) : null;
|
|
3374
|
+
let { store, nodeLookup, actions } = useInternalSolidFlow(), [ref$2, setRef] = createSignal(), bounds = createMemo(() => store.selectionRectMode === "nodes" ? getInternalNodesBounds(nodeLookup, { filter: (node) => !!node.selected }) : null);
|
|
3136
3375
|
createEffect(() => ({
|
|
3137
3376
|
el: ref$2(),
|
|
3138
3377
|
focusable: !store.disableKeyboardA11y
|
|
@@ -3140,13 +3379,13 @@ const NodeSelection = (props) => {
|
|
|
3140
3379
|
focusable && el?.focus({ preventScroll: !0 });
|
|
3141
3380
|
});
|
|
3142
3381
|
let onContextMenu = (event) => {
|
|
3143
|
-
let selectedNodes = store.
|
|
3382
|
+
let selectedNodes = store.selectedNodes;
|
|
3144
3383
|
props.onSelectionContextMenu?.({
|
|
3145
3384
|
nodes: selectedNodes,
|
|
3146
3385
|
event
|
|
3147
3386
|
});
|
|
3148
3387
|
}, onClick = (event) => {
|
|
3149
|
-
let selectedNodes = store.
|
|
3388
|
+
let selectedNodes = store.selectedNodes;
|
|
3150
3389
|
props.onSelectionClick?.({
|
|
3151
3390
|
nodes: selectedNodes,
|
|
3152
3391
|
event
|
|
@@ -3345,14 +3584,11 @@ const KeyHandler = (props) => {
|
|
|
3345
3584
|
}, handleWindowBlur = () => {
|
|
3346
3585
|
resetKeysAndSelection(), cancelPointerGestures();
|
|
3347
3586
|
}, handleDelete = async () => {
|
|
3348
|
-
let selectedNodes = store.
|
|
3587
|
+
let selectedNodes = store.selectedNodes, selectedEdges = store.selectedEdges;
|
|
3588
|
+
await deleteElements({
|
|
3349
3589
|
nodes: selectedNodes,
|
|
3350
3590
|
edges: selectedEdges
|
|
3351
3591
|
});
|
|
3352
|
-
(deletedNodes.length > 0 || deletedEdges.length > 0) && store.onDelete?.({
|
|
3353
|
-
nodes: deletedNodes,
|
|
3354
|
-
edges: deletedEdges
|
|
3355
|
-
});
|
|
3356
3592
|
};
|
|
3357
3593
|
return isServer || (createEventListenerMap(window, {
|
|
3358
3594
|
keydown: (event) => {
|
|
@@ -3370,7 +3606,7 @@ const KeyHandler = (props) => {
|
|
|
3370
3606
|
capture: !0,
|
|
3371
3607
|
passive: !0
|
|
3372
3608
|
})), null;
|
|
3373
|
-
};
|
|
3609
|
+
}, FLOW_PROP_KEYS = /* @__PURE__ */ "ariaLabelConfig.ariaLiveMessage.attributionPosition.autoPanOnConnect.autoPanOnNodeDrag.autoPanOnNodeFocus.autoPanOnSelection.autoPanSpeed.class.clickConnect.colorMode.colorModeSSR.connectionDragThreshold.connectionLineComponent.connectionLineContainerStyle.connectionLineStyle.connectionLineType.connectionMode.connectionRadius.defaultEdgeOptions.defaultEdges.defaultMarkerColor.defaultNodes.deleteKey.disableKeyboardA11y.edgeTypes.edges.edgesFocusable.elementsSelectable.elevateEdgesOnSelect.elevateNodesOnSelect.fitView.fitViewOptions.height.id.initialViewport.isValidConnection.maxZoom.minZoom.multiSelectionKey.noDragClass.noPanClass.noWheelClass.nodeClickDistance.nodeDragThreshold.nodeExtent.nodeOrigin.nodeTypes.nodes.nodesConnectable.nodesDraggable.nodesFocusable.onBeforeConnect.onBeforeDelete.onBeforeReconnect.onClickConnectEnd.onClickConnectStart.onConnect.onConnectEnd.onConnectStart.onDelete.onEdgeClick.onEdgeContextMenu.onEdgePointerEnter.onEdgePointerLeave.onEdgesDelete.onFlowError.onInit.onMove.onMoveEnd.onMoveStart.onNodeClick.onNodeContextMenu.onNodeDrag.onNodeDragStart.onNodeDragStop.onNodePointerEnter.onNodePointerLeave.onNodePointerMove.onNodesDelete.onPaneClick.onPaneContextMenu.onReconnect.onReconnectEnd.onReconnectStart.onSelectionChange.onSelectionClick.onSelectionContextMenu.onSelectionDrag.onSelectionDragStart.onSelectionDragStop.onSelectionEnd.onSelectionStart.onlyRenderVisibleElements.panActivationKey.panOnDrag.panOnScroll.panOnScrollMode.panOnScrollSpeed.paneClickDistance.preventScrolling.proOptions.selectNodesOnDrag.selectionKey.selectionMode.selectionOnDrag.snapGrid.style.translateExtent.viewport.width.zIndexMode.zoomActivationKey.zoomOnDoubleClick.zoomOnPinch.zoomOnScroll".split(".");
|
|
3374
3610
|
//#endregion
|
|
3375
3611
|
//#region src/components/SolidFlow.tsx
|
|
3376
3612
|
var _tmpl$$14 = /* @__PURE__ */ template("<div class=\"solid-flow__container solid-flow__viewport-back\">"), _tmpl$2 = /* @__PURE__ */ template("<div class=\"solid-flow__container solid-flow__edge-labels\">"), _tmpl$3 = /* @__PURE__ */ template("<div>");
|
|
@@ -3379,30 +3615,19 @@ const SolidFlow = (props) => {
|
|
|
3379
3615
|
let [domNodeRef, setDomNodeRef] = createSignal(), domNode, _props = merge({
|
|
3380
3616
|
...getDefaultFlowStateProps(),
|
|
3381
3617
|
colorMode: "light",
|
|
3382
|
-
deleteKeyCode: "Backspace",
|
|
3383
|
-
defaultViewport: {
|
|
3384
|
-
x: 0,
|
|
3385
|
-
y: 0,
|
|
3386
|
-
zoom: 1
|
|
3387
|
-
},
|
|
3388
|
-
multiSelectionKeyCode: isMacOs() ? "Meta" : "Control",
|
|
3389
3618
|
nodeClickDistance: 0,
|
|
3390
3619
|
panOnScroll: !1,
|
|
3391
|
-
panActivationKeyCode: "Space",
|
|
3392
3620
|
preventScrolling: !0,
|
|
3393
3621
|
panOnDrag: !0,
|
|
3394
3622
|
panOnScrollSpeed: .5,
|
|
3395
3623
|
panOnScrollMode: "free",
|
|
3396
3624
|
paneClickDistance: 0,
|
|
3397
|
-
reconnectRadius: 10,
|
|
3398
|
-
selectionKeyCode: "Shift",
|
|
3399
3625
|
selectionOnDrag: !1,
|
|
3400
3626
|
translateExtent: infiniteExtent,
|
|
3401
|
-
zoomActivationKeyCode: isMacOs() ? "Meta" : "Control",
|
|
3402
3627
|
zoomOnPinch: !0,
|
|
3403
3628
|
zoomOnDoubleClick: !0,
|
|
3404
3629
|
zoomOnScroll: !0
|
|
3405
|
-
}, props), htmlProps = omit(_props,
|
|
3630
|
+
}, props), htmlProps = omit(_props, ...FLOW_PROP_KEYS, "children"), TypedSolidFlowContext = SolidFlowContext, solidFlow = useContext(TypedSolidFlowContext) ?? createSolidFlow(_props), { store, actions } = solidFlow;
|
|
3406
3631
|
onSettled(() => (actions.applyInitialFitView(_props.fitView), actions.setConfig(_props), actions.setDomNode(domNode), () => {
|
|
3407
3632
|
actions.reset();
|
|
3408
3633
|
})), createEffect(() => domNodeRef(), (el) => {
|
|
@@ -3411,11 +3636,6 @@ const SolidFlow = (props) => {
|
|
|
3411
3636
|
actions.setWidth(el.clientWidth), actions.setHeight(el.clientHeight);
|
|
3412
3637
|
});
|
|
3413
3638
|
return observer.observe(el), () => observer.disconnect();
|
|
3414
|
-
}), createEffect(() => ({
|
|
3415
|
-
panZoom: store.panZoom,
|
|
3416
|
-
distance: _props.paneClickDistance
|
|
3417
|
-
}), ({ panZoom, distance }) => {
|
|
3418
|
-
panZoom?.setClickDistance(distance);
|
|
3419
3639
|
});
|
|
3420
3640
|
let selectedElements = createMemo(() => ({
|
|
3421
3641
|
nodes: store.selectedNodes,
|
|
@@ -3424,7 +3644,7 @@ const SolidFlow = (props) => {
|
|
|
3424
3644
|
createEffect(() => selectedElements(), (params) => {
|
|
3425
3645
|
untrack(() => _props.onSelectionChange)?.(params);
|
|
3426
3646
|
});
|
|
3427
|
-
let rootStyle = () => ({
|
|
3647
|
+
let asyncSeedGuard = () => (_props.nodes?.length, _props.edges?.length, null), rootStyle = () => ({
|
|
3428
3648
|
width: toPxString(_props.width),
|
|
3429
3649
|
height: toPxString(_props.height),
|
|
3430
3650
|
..._props.style
|
|
@@ -3457,6 +3677,7 @@ const SolidFlow = (props) => {
|
|
|
3457
3677
|
value: solidFlow,
|
|
3458
3678
|
get children() {
|
|
3459
3679
|
return [
|
|
3680
|
+
memo(() => asyncSeedGuard()),
|
|
3460
3681
|
createComponent(KeyHandler, {
|
|
3461
3682
|
get selectionKey() {
|
|
3462
3683
|
return _props.selectionKey;
|
|
@@ -3551,9 +3772,6 @@ const SolidFlow = (props) => {
|
|
|
3551
3772
|
return [
|
|
3552
3773
|
_tmpl$$14(),
|
|
3553
3774
|
createComponent(EdgeRenderer, {
|
|
3554
|
-
get reconnectRadius() {
|
|
3555
|
-
return _props.reconnectRadius;
|
|
3556
|
-
},
|
|
3557
3775
|
get onEdgeClick() {
|
|
3558
3776
|
return _props.onEdgeClick;
|
|
3559
3777
|
},
|
|
@@ -3565,9 +3783,6 @@ const SolidFlow = (props) => {
|
|
|
3565
3783
|
},
|
|
3566
3784
|
get onEdgePointerLeave() {
|
|
3567
3785
|
return _props.onEdgePointerLeave;
|
|
3568
|
-
},
|
|
3569
|
-
get defaultEdgeOptions() {
|
|
3570
|
-
return _props.defaultEdgeOptions;
|
|
3571
3786
|
}
|
|
3572
3787
|
}),
|
|
3573
3788
|
_tmpl$2(),
|
|
@@ -4163,24 +4378,23 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
|
|
|
4163
4378
|
nodeBorderRadius: 5,
|
|
4164
4379
|
nodeStrokeWidth: 2,
|
|
4165
4380
|
style: {}
|
|
4166
|
-
}), 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 =
|
|
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(() => ({
|
|
4167
4382
|
x: -store.viewport.x / store.viewport.zoom,
|
|
4168
4383
|
y: -store.viewport.y / store.viewport.zoom,
|
|
4169
4384
|
width: store.width / store.viewport.zoom,
|
|
4170
4385
|
height: store.height / store.viewport.zoom
|
|
4171
|
-
}),
|
|
4172
|
-
let
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4386
|
+
})), boundingRect = createMemo(() => {
|
|
4387
|
+
let view = viewBB();
|
|
4388
|
+
if (nodeLookup.size === 0) return view;
|
|
4389
|
+
let bounds = getInternalNodesBounds(nodeLookup);
|
|
4390
|
+
return !Number.isFinite(bounds.x) || !Number.isFinite(bounds.width) ? view : getBoundsOfRects(bounds, view);
|
|
4391
|
+
}), viewScale = createMemo(() => Math.max(boundingRect().width / _props.width, boundingRect().height / _props.height)), getViewWidth = () => viewScale() * _props.width, getViewHeight = () => viewScale() * _props.height, getOffset = () => 5 * viewScale(), getX = () => {
|
|
4392
|
+
let rect = boundingRect();
|
|
4393
|
+
return rect.x - (getViewWidth() - rect.width) / 2 - getOffset();
|
|
4177
4394
|
}, getY = () => {
|
|
4178
|
-
let
|
|
4179
|
-
return
|
|
4180
|
-
}, getViewboxWidth = () => getViewWidth() + getOffset() * 2, getViewboxHeight = () => getViewHeight() + getOffset() * 2, strokeWidth = () => _props.maskStrokeWidth ? _props.maskStrokeWidth *
|
|
4181
|
-
let currentNodeIds = store.nodes.map((node) => node.id), currentSet = new Set(currentNodeIds);
|
|
4182
|
-
return (prevNodeIds.length !== currentNodeIds.length || !prevNodeIds.every((id) => currentSet.has(id))) && (prevNodeIds = currentNodeIds), prevNodeIds;
|
|
4183
|
-
};
|
|
4395
|
+
let rect = boundingRect();
|
|
4396
|
+
return rect.y - (getViewHeight() - rect.height) / 2 - getOffset();
|
|
4397
|
+
}, getViewboxWidth = () => getViewWidth() + getOffset() * 2, getViewboxHeight = () => getViewHeight() + getOffset() * 2, strokeWidth = () => _props.maskStrokeWidth ? _props.maskStrokeWidth * viewScale() : void 0, nodeIds = createMemo(() => store.nodes.map((node) => node.id), { equals: (a, b) => a.length === b.length && a.every((id, i) => id === b[i]) });
|
|
4184
4398
|
return createComponent(Panel, mergeProps({
|
|
4185
4399
|
get position() {
|
|
4186
4400
|
return _props.position;
|
|
@@ -4211,7 +4425,7 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
|
|
|
4211
4425
|
domNode: el,
|
|
4212
4426
|
panZoom,
|
|
4213
4427
|
getTransform: () => store.transform,
|
|
4214
|
-
getViewScale
|
|
4428
|
+
getViewScale: viewScale
|
|
4215
4429
|
});
|
|
4216
4430
|
return setMinimap(instance), () => {
|
|
4217
4431
|
instance.destroy();
|
|
@@ -4272,9 +4486,7 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
|
|
|
4272
4486
|
get strokeWidth() {
|
|
4273
4487
|
return _props.nodeStrokeWidth;
|
|
4274
4488
|
},
|
|
4275
|
-
|
|
4276
|
-
return shapeRendering();
|
|
4277
|
-
},
|
|
4489
|
+
shapeRendering,
|
|
4278
4490
|
get width() {
|
|
4279
4491
|
return nodeDimensions().width;
|
|
4280
4492
|
},
|
|
@@ -4312,7 +4524,7 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
|
|
|
4312
4524
|
s: strokeWidth(),
|
|
4313
4525
|
h: labelledBy(),
|
|
4314
4526
|
r: `M${getX() - getOffset()},${getY() - getOffset()}h${getViewboxWidth() + getOffset() * 2}v${getViewboxHeight() + getOffset() * 2}h${-getViewboxWidth() - getOffset() * 2}z
|
|
4315
|
-
M${
|
|
4527
|
+
M${viewBB().x},${viewBB().y}h${viewBB().width}v${viewBB().height}h${-viewBB().width}z`
|
|
4316
4528
|
}), ({ e, t, a, o, i, n, s, h, r }, _p$) => {
|
|
4317
4529
|
e !== _p$?.e && setAttribute(_el$, "width", e), t !== _p$?.t && setAttribute(_el$, "height", t), a !== _p$?.a && setAttribute(_el$, "viewBox", a), o !== _p$?.o && setAttribute(_el$, "aria-labelledby", o), i !== _p$?.i && setStyleProperty(_el$, "--xy-minimap-mask-background-color-props", i), n !== _p$?.n && setStyleProperty(_el$, "--xy-minimap-mask-stroke-color-props", n), s !== _p$?.s && setStyleProperty(_el$, "--xy-minimap-mask-stroke-width-props", s), h !== _p$?.h && setAttribute(_el$2, "id", h), r !== _p$?.r && setAttribute(_el$3, "d", r);
|
|
4318
4530
|
}), _el$;
|