@dschz/solid-flow 0.3.0-next.3 → 0.3.0-next.4
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 +18 -0
- package/dist/index/index.d.ts +146 -59
- package/dist/index/index.js +182 -108
- package/dist/index/index.jsx +114 -65
- package/dist/styles/index.css +1 -1
- package/package.json +1 -1
package/dist/index/index.js
CHANGED
|
@@ -5,9 +5,18 @@ import { createMediaQuery } from "@solid-primitives/media";
|
|
|
5
5
|
import { createEventListener, createEventListenerMap } from "@solid-primitives/event-listener";
|
|
6
6
|
//#region src/contexts/edgeId.ts
|
|
7
7
|
const EdgeIdContext = createContext(null);
|
|
8
|
+
/**
|
|
9
|
+
* Returns the id of the edge this component is rendered inside. Available
|
|
10
|
+
* anywhere in a custom edge's subtree (provided by the edge wrapper), so
|
|
11
|
+
* nested components — like a custom edge label — can learn their host edge
|
|
12
|
+
* without prop drilling.
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
15
|
+
* @returns a reactive accessor for the surrounding edge's id
|
|
16
|
+
*/
|
|
8
17
|
function useEdgeId() {
|
|
9
18
|
let ctx = useContext(EdgeIdContext);
|
|
10
|
-
if (!ctx) throw Error("solid-flow:
|
|
19
|
+
if (!ctx) throw Error("solid-flow: useEdgeId must be called inside an edge component (anywhere under a custom edge's subtree)");
|
|
11
20
|
return ctx;
|
|
12
21
|
}
|
|
13
22
|
//#endregion
|
|
@@ -281,11 +290,13 @@ const EdgeReconnectAnchor = (props) => {
|
|
|
281
290
|
size: 25,
|
|
282
291
|
reconnecting: !1,
|
|
283
292
|
style: {}
|
|
284
|
-
}), rest = omit(_props, "type", "class", "style", "position", "size", "reconnecting", "children"), { store, nodeLookup, edgeLookup, actions } = useInternalSolidFlow(), edgeId = useEdgeId(), [reconnecting, setReconnecting] = createSignal(!1);
|
|
293
|
+
}), rest = omit(_props, "type", "class", "style", "position", "size", "reconnecting", "onReconnectingChange", "children"), { store, nodeLookup, edgeLookup, actions } = useInternalSolidFlow(), edgeId = useEdgeId(), [reconnecting, setReconnecting] = createSignal(!1);
|
|
285
294
|
if (!edgeId()) throw Error("[solid-flow]: EdgeReconnectAnchor must be used within an Edge component");
|
|
286
|
-
let edge = () => edgeLookup[edgeId()],
|
|
295
|
+
let edge = () => edgeLookup[edgeId()], isReconnecting = () => _props.reconnecting || reconnecting(), setReconnectingState = (next) => {
|
|
296
|
+
setReconnecting(next), _props.onReconnectingChange?.(next);
|
|
297
|
+
}, onPointerDown = (event) => {
|
|
287
298
|
if (event.button !== 0) return;
|
|
288
|
-
|
|
299
|
+
setReconnectingState(!0), store.onReconnectStart?.(event, edge(), _props.type);
|
|
289
300
|
let opposite = _props.type === "target" ? {
|
|
290
301
|
nodeId: edge().source,
|
|
291
302
|
handleId: edge().sourceHandle ?? null,
|
|
@@ -309,7 +320,9 @@ const EdgeReconnectAnchor = (props) => {
|
|
|
309
320
|
edgeUpdaterType: opposite.type,
|
|
310
321
|
cancelConnection: actions.cancelConnection,
|
|
311
322
|
panBy: actions.panBy,
|
|
312
|
-
updateConnection:
|
|
323
|
+
updateConnection: (connection) => {
|
|
324
|
+
actions.setConnection(connection), flush();
|
|
325
|
+
},
|
|
313
326
|
isValidConnection: store.isValidConnection,
|
|
314
327
|
onConnectStart: store.onConnectStart,
|
|
315
328
|
onConnectEnd: store.onConnectEnd,
|
|
@@ -321,7 +334,7 @@ const EdgeReconnectAnchor = (props) => {
|
|
|
321
334
|
newEdge = store.onBeforeReconnect?.(newEdge, edge()) ?? newEdge, newEdge && actions.setEdges((edges) => edges.map((e) => e.id === edge().id ? newEdge : e)), store.onReconnect?.(edge(), connection);
|
|
322
335
|
},
|
|
323
336
|
onReconnectEnd: (event, connectionState) => {
|
|
324
|
-
|
|
337
|
+
setReconnectingState(!1), store.onReconnectEnd?.(event, edge(), opposite.type, connectionState);
|
|
325
338
|
},
|
|
326
339
|
getTransform: () => store.transform,
|
|
327
340
|
getFromHandle: () => store.connection.fromHandle,
|
|
@@ -344,7 +357,7 @@ const EdgeReconnectAnchor = (props) => {
|
|
|
344
357
|
var _el$ = _tmpl$$32();
|
|
345
358
|
return _el$.$$pointerdown = onPointerDown, insert(_el$, createComponent(Show, {
|
|
346
359
|
get when() {
|
|
347
|
-
return !
|
|
360
|
+
return !isReconnecting();
|
|
348
361
|
},
|
|
349
362
|
get children() {
|
|
350
363
|
return _props.children;
|
|
@@ -407,7 +420,6 @@ const A11yDescriptions = () => {
|
|
|
407
420
|
let [store, setStore] = createStore(edges);
|
|
408
421
|
return [store, setStore];
|
|
409
422
|
}, 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(() => {
|
|
410
|
-
if (!source.onlyRenderVisibleElements) return null;
|
|
411
423
|
let { width, height } = source;
|
|
412
424
|
if (!width || !height) return null;
|
|
413
425
|
let [tx, ty, zoom] = source.transform, zoomBucket = 2 ** Math.floor(Math.log2(zoom)), bucketWidth = width / zoomBucket, bucketHeight = height / zoomBucket, stepX = bucketWidth * STEP, stepY = bucketHeight * STEP, centerX = (width / 2 - tx) / zoom, centerY = (height / 2 - ty) / zoom, quantizedX = Math.round(centerX / stepX) * stepX, quantizedY = Math.round(centerY / stepY) * stepY, halfWidth = bucketWidth * 1, halfHeight = bucketHeight * 1;
|
|
@@ -471,7 +483,7 @@ const A11yDescriptions = () => {
|
|
|
471
483
|
selectNodesOnDrag: !0,
|
|
472
484
|
elevateNodesOnSelect: !0,
|
|
473
485
|
zIndexMode: "basic",
|
|
474
|
-
onlyRenderVisibleElements: !
|
|
486
|
+
onlyRenderVisibleElements: !1,
|
|
475
487
|
disableKeyboardA11y: !1,
|
|
476
488
|
defaultMarkerColor: "#b1b1b7",
|
|
477
489
|
ariaLiveMessage: "",
|
|
@@ -761,9 +773,17 @@ const createLayoutedEdges = (source) => {
|
|
|
761
773
|
return config().zIndexMode;
|
|
762
774
|
}
|
|
763
775
|
}), nodeLookup = new RecordMapFacade(internalNodes), initialViewport = getInitialViewport(_props.fitView, _props.initialViewport, _props.width ?? 0, _props.height ?? 0, nodeLookup), [viewportStore, setViewportStore] = createStore(_props.viewport ?? initialViewport);
|
|
764
|
-
createEffect(() =>
|
|
776
|
+
createEffect(() => {
|
|
777
|
+
let next = config().nodes;
|
|
778
|
+
for (let node of next);
|
|
779
|
+
return { next };
|
|
780
|
+
}, ({ next }) => {
|
|
765
781
|
setNodesStore(() => next);
|
|
766
|
-
}, { defer: !0 }), createEffect(() =>
|
|
782
|
+
}, { defer: !0 }), createEffect(() => {
|
|
783
|
+
let next = config().edges;
|
|
784
|
+
for (let edge of next);
|
|
785
|
+
return { next };
|
|
786
|
+
}, ({ next }) => {
|
|
767
787
|
setEdgesStore(() => next);
|
|
768
788
|
}, { defer: !0 }), createEffect(() => config().viewport, (next) => {
|
|
769
789
|
next && setViewportStore(() => next);
|
|
@@ -924,9 +944,6 @@ const createLayoutedEdges = (source) => {
|
|
|
924
944
|
return zoomActivationKeyPressed();
|
|
925
945
|
}
|
|
926
946
|
}), cullingViewport = createCullingViewport({
|
|
927
|
-
get onlyRenderVisibleElements() {
|
|
928
|
-
return store.onlyRenderVisibleElements;
|
|
929
|
-
},
|
|
930
947
|
get width() {
|
|
931
948
|
return store.width;
|
|
932
949
|
},
|
|
@@ -2095,9 +2112,18 @@ const GroupNode = (props) => (() => {
|
|
|
2095
2112
|
};
|
|
2096
2113
|
}), dragging;
|
|
2097
2114
|
}, NodeIdContext = createContext(null);
|
|
2115
|
+
/**
|
|
2116
|
+
* Returns the id of the node this component is rendered inside. Available
|
|
2117
|
+
* anywhere in a custom node's subtree (provided by the node wrapper), so
|
|
2118
|
+
* nested components — like a custom `Handle` — can learn their host node
|
|
2119
|
+
* without prop drilling.
|
|
2120
|
+
*
|
|
2121
|
+
* @public
|
|
2122
|
+
* @returns a reactive accessor for the surrounding node's id
|
|
2123
|
+
*/
|
|
2098
2124
|
function useNodeId() {
|
|
2099
2125
|
let ctx = useContext(NodeIdContext);
|
|
2100
|
-
if (!ctx) throw Error("solid-flow:
|
|
2126
|
+
if (!ctx) throw Error("solid-flow: useNodeId must be called inside a node component (anywhere under a custom node's subtree)");
|
|
2101
2127
|
return ctx;
|
|
2102
2128
|
}
|
|
2103
2129
|
//#endregion
|
|
@@ -2105,7 +2131,12 @@ function useNodeId() {
|
|
|
2105
2131
|
var _tmpl$$27 = /* @__PURE__ */ template("<div>");
|
|
2106
2132
|
/** Internal per-node wrapper: dragging, selection, a11y, measurement, viewport culling, and the dynamic node component. */
|
|
2107
2133
|
const NodeWrapper = (props) => {
|
|
2108
|
-
let { store, nodeLookup, parentIds, actions } = useInternalSolidFlow(), [nodeRef, setNodeRef] = createSignal(), node = () => nodeLookup.get(props.nodeId)
|
|
2134
|
+
let { store, nodeLookup, parentIds, actions } = useInternalSolidFlow(), [nodeRef, setNodeRef] = createSignal(), node = () => nodeLookup.get(props.nodeId);
|
|
2135
|
+
onCleanup(() => {
|
|
2136
|
+
let el = nodeRef();
|
|
2137
|
+
el && props.resizeObserver?.unobserve(el);
|
|
2138
|
+
});
|
|
2139
|
+
let nodeId = () => node().id, nodeType = () => node().type ?? "default", deletable = () => node().deletable ?? !0, selectable = () => node().selectable ?? store.elementsSelectable, focusable = () => node().focusable ?? store.nodesFocusable, draggable = () => node().draggable ?? store.nodesDraggable, connectable = () => node().connectable ?? store.nodesConnectable, userNode = () => node().internals.userNode, nodeTypeValid = () => nodeType() in store.nodeTypes, nodeComponent = () => store.nodeTypes[nodeType()], isParentNode = () => !!parentIds[node().id], transform = () => {
|
|
2109
2140
|
let { x, y } = node().internals.positionAbsolute;
|
|
2110
2141
|
return `translate(${x}px, ${y}px)`;
|
|
2111
2142
|
}, sizeStyle = () => {
|
|
@@ -2688,35 +2719,53 @@ const MarkerDefinition = () => {
|
|
|
2688
2719
|
var _tmpl$$23 = /* @__PURE__ */ template("<div class=solid-flow__edges><!><!>");
|
|
2689
2720
|
/** Internal renderer iterating the edge id list into `EdgeWrapper`s. */
|
|
2690
2721
|
const EdgeRenderer = (props) => {
|
|
2691
|
-
let { store } = useInternalSolidFlow()
|
|
2722
|
+
let { store, actions } = useInternalSolidFlow(), [focusedEdgeId, setFocusedEdgeId] = createSignal(null), onFocusIn = (event) => {
|
|
2723
|
+
let edgeElement = event.target.closest("[data-id]");
|
|
2724
|
+
setFocusedEdgeId(edgeElement?.getAttribute("data-id") ?? null);
|
|
2725
|
+
};
|
|
2692
2726
|
var _el$ = _tmpl$$23(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
|
|
2693
|
-
return insert(_el$, createComponent(MarkerDefinition, {}), _el$2), insert(_el$, createComponent(For, {
|
|
2727
|
+
return _el$.$$focusout = () => setFocusedEdgeId(null), _el$.$$focusin = onFocusIn, insert(_el$, createComponent(MarkerDefinition, {}), _el$2), insert(_el$, createComponent(For, {
|
|
2694
2728
|
get each() {
|
|
2695
2729
|
return store.visibleEdgeIds;
|
|
2696
2730
|
},
|
|
2697
|
-
children: (edgeId) =>
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2731
|
+
children: (edgeId) => {
|
|
2732
|
+
let unmounted = createMemo(() => {
|
|
2733
|
+
if (!store.onlyRenderVisibleElements || focusedEdgeId() === edgeId) return !1;
|
|
2734
|
+
let edge = actions.getEdge(edgeId);
|
|
2735
|
+
return !!edge && isEdgeCulled(edge, store.cullingViewport);
|
|
2736
|
+
});
|
|
2737
|
+
return createComponent(Show, {
|
|
2738
|
+
get when() {
|
|
2739
|
+
return !unmounted();
|
|
2740
|
+
},
|
|
2741
|
+
get children() {
|
|
2742
|
+
return createComponent(EdgeWrapper, {
|
|
2743
|
+
edgeId,
|
|
2744
|
+
get onEdgeClick() {
|
|
2745
|
+
return props.onEdgeClick;
|
|
2746
|
+
},
|
|
2747
|
+
get onEdgeContextMenu() {
|
|
2748
|
+
return props.onEdgeContextMenu;
|
|
2749
|
+
},
|
|
2750
|
+
get onEdgePointerEnter() {
|
|
2751
|
+
return props.onEdgePointerEnter;
|
|
2752
|
+
},
|
|
2753
|
+
get onEdgePointerLeave() {
|
|
2754
|
+
return props.onEdgePointerLeave;
|
|
2755
|
+
}
|
|
2756
|
+
});
|
|
2757
|
+
}
|
|
2758
|
+
});
|
|
2759
|
+
}
|
|
2712
2760
|
}), _el$3), _el$;
|
|
2713
2761
|
};
|
|
2762
|
+
delegateEvents(["focusin", "focusout"]);
|
|
2714
2763
|
//#endregion
|
|
2715
2764
|
//#region src/components/container/NodeRenderer.tsx
|
|
2716
2765
|
var _tmpl$$22 = /* @__PURE__ */ template("<div class=\"solid-flow__container solid-flow__nodes\">");
|
|
2717
2766
|
/** Internal renderer iterating the node id list into `NodeWrapper`s; owns the shared measurement `ResizeObserver`. */
|
|
2718
2767
|
const NodeRenderer = (props) => {
|
|
2719
|
-
let { actions, store } = useInternalSolidFlow(), resizeObserver = isServer ? void 0 : new ResizeObserver((entries) => {
|
|
2768
|
+
let { actions, store, nodeLookup } = useInternalSolidFlow(), resizeObserver = isServer ? void 0 : new ResizeObserver((entries) => {
|
|
2720
2769
|
actions.requestUpdateNodeInternals(entries.map((entry) => {
|
|
2721
2770
|
let id = entry.target.getAttribute("data-id");
|
|
2722
2771
|
return [id, {
|
|
@@ -2729,44 +2778,63 @@ const NodeRenderer = (props) => {
|
|
|
2729
2778
|
onCleanup(() => {
|
|
2730
2779
|
resizeObserver?.disconnect();
|
|
2731
2780
|
});
|
|
2781
|
+
let [focusedNodeId, setFocusedNodeId] = createSignal(null), onFocusIn = (event) => {
|
|
2782
|
+
let nodeElement = event.target.closest("[data-id]");
|
|
2783
|
+
setFocusedNodeId(nodeElement?.getAttribute("data-id") ?? null);
|
|
2784
|
+
};
|
|
2732
2785
|
var _el$ = _tmpl$$22();
|
|
2733
|
-
return insert(_el$, createComponent(For, {
|
|
2786
|
+
return _el$.$$focusout = () => setFocusedNodeId(null), _el$.$$focusin = onFocusIn, insert(_el$, createComponent(For, {
|
|
2734
2787
|
get each() {
|
|
2735
2788
|
return store.visibleNodeIds;
|
|
2736
2789
|
},
|
|
2737
|
-
children: (nodeId) =>
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
return
|
|
2742
|
-
}
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2790
|
+
children: (nodeId) => {
|
|
2791
|
+
let unmounted = createMemo(() => {
|
|
2792
|
+
if (!store.onlyRenderVisibleElements || focusedNodeId() === nodeId) return !1;
|
|
2793
|
+
let node = nodeLookup.get(nodeId);
|
|
2794
|
+
return !!node && isNodeCulled(node, store.cullingViewport);
|
|
2795
|
+
});
|
|
2796
|
+
return createComponent(Show, {
|
|
2797
|
+
get when() {
|
|
2798
|
+
return !unmounted();
|
|
2799
|
+
},
|
|
2800
|
+
get children() {
|
|
2801
|
+
return createComponent(NodeWrapper, {
|
|
2802
|
+
nodeId,
|
|
2803
|
+
resizeObserver,
|
|
2804
|
+
get nodeClickDistance() {
|
|
2805
|
+
return props.nodeClickDistance;
|
|
2806
|
+
},
|
|
2807
|
+
get onNodeClick() {
|
|
2808
|
+
return props.onNodeClick;
|
|
2809
|
+
},
|
|
2810
|
+
get onNodePointerEnter() {
|
|
2811
|
+
return props.onNodePointerEnter;
|
|
2812
|
+
},
|
|
2813
|
+
get onNodePointerMove() {
|
|
2814
|
+
return props.onNodePointerMove;
|
|
2815
|
+
},
|
|
2816
|
+
get onNodePointerLeave() {
|
|
2817
|
+
return props.onNodePointerLeave;
|
|
2818
|
+
},
|
|
2819
|
+
get onNodeDrag() {
|
|
2820
|
+
return props.onNodeDrag;
|
|
2821
|
+
},
|
|
2822
|
+
get onNodeDragStart() {
|
|
2823
|
+
return props.onNodeDragStart;
|
|
2824
|
+
},
|
|
2825
|
+
get onNodeDragStop() {
|
|
2826
|
+
return props.onNodeDragStop;
|
|
2827
|
+
},
|
|
2828
|
+
get onNodeContextMenu() {
|
|
2829
|
+
return props.onNodeContextMenu;
|
|
2830
|
+
}
|
|
2831
|
+
});
|
|
2832
|
+
}
|
|
2833
|
+
});
|
|
2834
|
+
}
|
|
2768
2835
|
})), _el$;
|
|
2769
2836
|
};
|
|
2837
|
+
delegateEvents(["focusin", "focusout"]);
|
|
2770
2838
|
//#endregion
|
|
2771
2839
|
//#region src/components/container/Pane.tsx
|
|
2772
2840
|
var _tmpl$$21 = /* @__PURE__ */ template("<div class=\"solid-flow__container solid-flow__pane\">");
|
|
@@ -3167,25 +3235,14 @@ const Attribution = (props) => createComponent(Show, {
|
|
|
3167
3235
|
* `const { flow, commands } = useSolidFlow()`.
|
|
3168
3236
|
*
|
|
3169
3237
|
* @public
|
|
3170
|
-
* @returns the flow's read struct
|
|
3238
|
+
* @returns the flow's read struct and write surface
|
|
3171
3239
|
*/
|
|
3172
3240
|
function useSolidFlow() {
|
|
3173
|
-
let { flow, commands
|
|
3241
|
+
let { flow, commands } = useInternalSolidFlow();
|
|
3174
3242
|
return {
|
|
3175
3243
|
...commands,
|
|
3176
3244
|
flow,
|
|
3177
|
-
commands
|
|
3178
|
-
getInternalNode,
|
|
3179
|
-
getNode: (id) => getInternalNode(id)?.internals.userNode,
|
|
3180
|
-
getNodes: (ids) => ids ? ids.flatMap((id) => {
|
|
3181
|
-
let userNode = flow.internalNodes[id]?.internals.userNode;
|
|
3182
|
-
return userNode ? [userNode] : [];
|
|
3183
|
-
}) : [...flow.nodes],
|
|
3184
|
-
getEdge: (id) => edgeLookup[id],
|
|
3185
|
-
getEdges: (ids) => ids ? ids.flatMap((id) => edgeLookup[id] ? [edgeLookup[id]] : []) : [...flow.edges],
|
|
3186
|
-
getViewport: () => snapshot(store.viewport),
|
|
3187
|
-
getZoom: () => flow.viewport.zoom,
|
|
3188
|
-
getHandleConnections: ({ type, id, nodeId }) => Object.values(flow.connections[connectionKey(nodeId, type, id ?? null)] ?? {})
|
|
3245
|
+
commands
|
|
3189
3246
|
};
|
|
3190
3247
|
}
|
|
3191
3248
|
//#endregion
|
|
@@ -3262,7 +3319,7 @@ const KeyHandler = (props) => {
|
|
|
3262
3319
|
}), null;
|
|
3263
3320
|
};
|
|
3264
3321
|
//#endregion
|
|
3265
|
-
//#region src/components/SolidFlow
|
|
3322
|
+
//#region src/components/SolidFlow.tsx
|
|
3266
3323
|
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>");
|
|
3267
3324
|
/** The flow canvas component: renders nodes and edges and wires up viewport and interactions. */
|
|
3268
3325
|
const SolidFlow = (props) => {
|
|
@@ -3627,19 +3684,6 @@ function useViewport() {
|
|
|
3627
3684
|
return () => flow.viewport;
|
|
3628
3685
|
}
|
|
3629
3686
|
//#endregion
|
|
3630
|
-
//#region src/hooks/useHandleEdgeSelect.ts
|
|
3631
|
-
/** Returns a callback applying edge-selection semantics for the given edge id. */
|
|
3632
|
-
function useHandleEdgeSelect() {
|
|
3633
|
-
let { store, edgeLookup, actions } = useInternalSolidFlow();
|
|
3634
|
-
return (id) => {
|
|
3635
|
-
let edge = edgeLookup[id];
|
|
3636
|
-
edge && (edge.selectable || store.elementsSelectable && edge.selectable === void 0) && (actions.setSelectionRect(void 0), actions.setSelectionRectMode(void 0), edge.selected ? edge.selected && store.multiselectionKeyPressed && actions.unselectNodesAndEdges({
|
|
3637
|
-
nodes: [],
|
|
3638
|
-
edges: [edge]
|
|
3639
|
-
}) : actions.addSelectedEdges([id]));
|
|
3640
|
-
};
|
|
3641
|
-
}
|
|
3642
|
-
//#endregion
|
|
3643
3687
|
//#region src/hooks/useInitialized.ts
|
|
3644
3688
|
/**
|
|
3645
3689
|
* Hook for seeing if all nodes have been measured.
|
|
@@ -3669,11 +3713,16 @@ function useViewportInitialized() {
|
|
|
3669
3713
|
//#endregion
|
|
3670
3714
|
//#region src/hooks/useInternalNode.ts
|
|
3671
3715
|
/**
|
|
3672
|
-
* Hook to get an internal node
|
|
3716
|
+
* Hook to get an internal node (the node enriched with measured dimensions,
|
|
3717
|
+
* absolute position, and z-order) by id.
|
|
3718
|
+
*
|
|
3719
|
+
* The id is an accessor (not a plain string) on purpose: passing a raw
|
|
3720
|
+
* reactive read like `props.nodeId` would capture the value once and silently
|
|
3721
|
+
* lose reactivity — `useInternalNode(() => props.nodeId)` keeps it live.
|
|
3673
3722
|
*
|
|
3674
3723
|
* @public
|
|
3675
|
-
* @param id - the node id
|
|
3676
|
-
* @returns an accessor with
|
|
3724
|
+
* @param id - a reactive accessor for the node id
|
|
3725
|
+
* @returns an accessor with the internal node, or undefined while absent
|
|
3677
3726
|
*/
|
|
3678
3727
|
function useInternalNode(id) {
|
|
3679
3728
|
let { flow } = useInternalSolidFlow();
|
|
@@ -3784,7 +3833,6 @@ const DEFAULT_SIZE = {
|
|
|
3784
3833
|
let _props = propDefaults(props, {
|
|
3785
3834
|
variant: "dots",
|
|
3786
3835
|
gap: 20,
|
|
3787
|
-
size: 1,
|
|
3788
3836
|
lineWidth: 1,
|
|
3789
3837
|
style: {}
|
|
3790
3838
|
}), { store } = useInternalSolidFlow(), isDots = () => _props.variant === "dots", isCross = () => _props.variant === "cross", patternId = () => `background-pattern-${store.id}-${_props.id ?? ""}`, scaledSize = () => (_props.size ?? DEFAULT_SIZE[_props.variant]) * store.viewport.zoom, gapXY = () => Array.isArray(_props.gap) ? _props.gap : [_props.gap, _props.gap], scaledGap = () => [gapXY()[0] * store.viewport.zoom || 1, gapXY()[1] * store.viewport.zoom || 1], patternDimensions = () => isCross() ? [scaledSize(), scaledSize()] : scaledGap(), patternOffset = () => isDots() ? [scaledSize() / 2, scaledSize() / 2] : [patternDimensions()[0] / 2, patternDimensions()[1] / 2];
|
|
@@ -4016,18 +4064,19 @@ const Unlock = () => _tmpl$$5(), Controls = (props) => {
|
|
|
4016
4064
|
//#endregion
|
|
4017
4065
|
//#region src/plugins/minimap/MiniMapNode.tsx
|
|
4018
4066
|
var _tmpl$$4 = /* @__PURE__ */ template("<svg><rect></svg>", 2);
|
|
4067
|
+
/** The default minimap node: a rounded rect. Custom `nodeComponent`s can wrap it. */
|
|
4019
4068
|
const MiniMapNode = (props) => {
|
|
4020
4069
|
let _props = propDefaults(props, {
|
|
4021
4070
|
borderRadius: 5,
|
|
4022
4071
|
width: 0,
|
|
4023
4072
|
height: 0
|
|
4024
|
-
}), style$1 = () => Object.entries({
|
|
4025
|
-
fill:
|
|
4073
|
+
}), fill = () => _props.color ?? _props.style?.background ?? _props.style?.["background-color"], style$1 = () => Object.entries({
|
|
4074
|
+
fill: fill(),
|
|
4026
4075
|
stroke: _props.strokeColor,
|
|
4027
4076
|
"stroke-width": _props.strokeWidth
|
|
4028
4077
|
}).filter(([_, value]) => value !== void 0).reduce((acc, [key, value]) => (acc[key] = value, acc), {});
|
|
4029
4078
|
var _el$ = _tmpl$$4();
|
|
4030
|
-
return effect(() => ({
|
|
4079
|
+
return addEvent(_el$, "click", _props.onClick ? (event) => _props.onClick(event, _props.id) : void 0, !0), effect(() => ({
|
|
4031
4080
|
e: [
|
|
4032
4081
|
"solid-flow__minimap-node",
|
|
4033
4082
|
{ selected: !!_props.selected },
|
|
@@ -4045,6 +4094,7 @@ const MiniMapNode = (props) => {
|
|
|
4045
4094
|
className(_el$, e, _p$?.e), t !== _p$?.t && setAttribute(_el$, "x", t), a !== _p$?.a && setAttribute(_el$, "y", a), o !== _p$?.o && setAttribute(_el$, "rx", o), i !== _p$?.i && setAttribute(_el$, "ry", i), n !== _p$?.n && setAttribute(_el$, "width", n), s !== _p$?.s && setAttribute(_el$, "height", s), h !== _p$?.h && setAttribute(_el$, "shape-rendering", h), style(_el$, r, _p$?.r);
|
|
4046
4095
|
}), _el$;
|
|
4047
4096
|
};
|
|
4097
|
+
delegateEvents(["click"]);
|
|
4048
4098
|
//#endregion
|
|
4049
4099
|
//#region src/plugins/minimap/MiniMap.tsx
|
|
4050
4100
|
var _tmpl$$3 = /* @__PURE__ */ template("<svg class=solid-flow__minimap-svg role=img><title></title><path class=solid-flow__minimap-mask fill-rule=evenodd pointer-events=none>");
|
|
@@ -4060,7 +4110,7 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
|
|
|
4060
4110
|
nodeBorderRadius: 5,
|
|
4061
4111
|
nodeStrokeWidth: 2,
|
|
4062
4112
|
style: {}
|
|
4063
|
-
}), paneProps = omit(_props, "class", "style", "position", "nodeClass", "nodeStrokeColor", "nodeColor", "pannable", "zoomable", "inversePan", "zoomStep", "bgColor", "width", "height", "maskColor", "maskStrokeColor", "maskStrokeWidth", "nodeBorderRadius", "nodeStrokeWidth"), 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}`), getViewBB = () => ({
|
|
4113
|
+
}), 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}`), getViewBB = () => ({
|
|
4064
4114
|
x: -store.viewport.x / store.viewport.zoom,
|
|
4065
4115
|
y: -store.viewport.y / store.viewport.zoom,
|
|
4066
4116
|
width: store.width / store.viewport.zoom,
|
|
@@ -4127,8 +4177,19 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
|
|
|
4127
4177
|
}), ({ instance, options }) => {
|
|
4128
4178
|
instance?.update(options);
|
|
4129
4179
|
});
|
|
4180
|
+
let onSvgClick = (event) => {
|
|
4181
|
+
if (!_props.onClick) return;
|
|
4182
|
+
let [x, y] = minimap()?.pointer(event) ?? [0, 0];
|
|
4183
|
+
_props.onClick(event, {
|
|
4184
|
+
x,
|
|
4185
|
+
y
|
|
4186
|
+
});
|
|
4187
|
+
}, onSvgNodeClick = (event, nodeId) => {
|
|
4188
|
+
let node = nodeLookup.get(nodeId)?.internals.userNode;
|
|
4189
|
+
node && _props.onNodeClick?.(event, node);
|
|
4190
|
+
};
|
|
4130
4191
|
var _el$ = _tmpl$$3(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
|
|
4131
|
-
return ref(() => setRef, _el$), insert(_el$2, () => store.ariaLabelConfig["minimap.ariaLabel"]), insert(_el$, createComponent(For, {
|
|
4192
|
+
return addEvent(_el$, "click", _props.onClick ? onSvgClick : void 0, !0), ref(() => setRef, _el$), insert(_el$2, () => store.ariaLabelConfig["minimap.ariaLabel"]), insert(_el$, createComponent(For, {
|
|
4132
4193
|
keyed: !1,
|
|
4133
4194
|
get each() {
|
|
4134
4195
|
return nodeIds();
|
|
@@ -4139,7 +4200,13 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
|
|
|
4139
4200
|
get when() {
|
|
4140
4201
|
return memo(() => !!nodeVisible())() ? getNodeDimensions(node()) : nodeVisible();
|
|
4141
4202
|
},
|
|
4142
|
-
children: (nodeDimensions) => createComponent(
|
|
4203
|
+
children: (nodeDimensions) => createComponent(Dynamic, {
|
|
4204
|
+
get component() {
|
|
4205
|
+
return _props.nodeComponent ?? MiniMapNode;
|
|
4206
|
+
},
|
|
4207
|
+
get id() {
|
|
4208
|
+
return nodeId();
|
|
4209
|
+
},
|
|
4143
4210
|
get x() {
|
|
4144
4211
|
return node().internals.positionAbsolute.x;
|
|
4145
4212
|
},
|
|
@@ -4172,6 +4239,12 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
|
|
|
4172
4239
|
},
|
|
4173
4240
|
get class() {
|
|
4174
4241
|
return nodeClassFunc().call(null, node());
|
|
4242
|
+
},
|
|
4243
|
+
get style() {
|
|
4244
|
+
return node().style;
|
|
4245
|
+
},
|
|
4246
|
+
get onClick() {
|
|
4247
|
+
return _props.onNodeClick ? onSvgNodeClick : void 0;
|
|
4175
4248
|
}
|
|
4176
4249
|
})
|
|
4177
4250
|
});
|
|
@@ -4194,6 +4267,7 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
|
|
|
4194
4267
|
});
|
|
4195
4268
|
} }));
|
|
4196
4269
|
};
|
|
4270
|
+
delegateEvents(["click"]);
|
|
4197
4271
|
//#endregion
|
|
4198
4272
|
//#region src/plugins/nodeResizer/ResizeControl.tsx
|
|
4199
4273
|
var _tmpl$$2 = /* @__PURE__ */ template("<div>");
|
|
@@ -4371,7 +4445,7 @@ const EdgeToolbar = (props) => {
|
|
|
4371
4445
|
var _tmpl$ = /* @__PURE__ */ template("<div>");
|
|
4372
4446
|
/** Toolbar attached to a node, rendered above the graph so it does not scale with zoom. */
|
|
4373
4447
|
const NodeToolbar = (props) => {
|
|
4374
|
-
let { store } = useInternalSolidFlow(), {
|
|
4448
|
+
let { store } = useInternalSolidFlow(), { flow, getNodesBounds } = useSolidFlow(), _props = propDefaults(props, {
|
|
4375
4449
|
offset: 10,
|
|
4376
4450
|
position: "top",
|
|
4377
4451
|
align: "center",
|
|
@@ -4380,7 +4454,7 @@ const NodeToolbar = (props) => {
|
|
|
4380
4454
|
let id = useContext(NodeIdContext);
|
|
4381
4455
|
return id ? id() : "";
|
|
4382
4456
|
}, toolbarNodes = () => (Array.isArray(_props.nodeId) ? _props.nodeId : [_props.nodeId ?? ctxNodeId()]).reduce((res, nodeId) => {
|
|
4383
|
-
let node =
|
|
4457
|
+
let node = flow.internalNodes[nodeId];
|
|
4384
4458
|
return node && res.push(node), res;
|
|
4385
4459
|
}, []), transform = () => {
|
|
4386
4460
|
let nodeRect = getNodesBounds(toolbarNodes());
|
|
@@ -4388,7 +4462,7 @@ const NodeToolbar = (props) => {
|
|
|
4388
4462
|
}, zIndex = () => {
|
|
4389
4463
|
let nodes = toolbarNodes();
|
|
4390
4464
|
return nodes.length === 0 ? 1 : Math.max(...nodes.map((node) => (node.internals.z || 5) + 1));
|
|
4391
|
-
}, selectedNodesCount = () =>
|
|
4465
|
+
}, selectedNodesCount = () => flow.selection.nodes.length, isActive = () => {
|
|
4392
4466
|
let nodes = toolbarNodes();
|
|
4393
4467
|
return typeof _props.isVisible == "boolean" ? _props.isVisible : nodes.length === 1 && !!nodes[0].selected && selectedNodesCount() === 1;
|
|
4394
4468
|
}, showPortal = () => !!(store.domNode && isActive() && toolbarNodes().length > 0);
|
|
@@ -4423,4 +4497,4 @@ const NodeToolbar = (props) => {
|
|
|
4423
4497
|
});
|
|
4424
4498
|
}, SelectionMode = SelectionMode$1, getEdgeCenter = getEdgeCenter$1, getBezierEdgeCenter = getBezierEdgeCenter$1;
|
|
4425
4499
|
//#endregion
|
|
4426
|
-
export { Background, BaseEdge, BezierEdge, BezierEdgeInternal, ConnectionLine, ConnectionLineType, ConnectionMode, ControlButton, Controls, DefaultNode, EdgeLabel, EdgeLabelRenderer, EdgeReconnectAnchor, EdgeRenderer, EdgeToolbar, EdgeWrapper, GroupNode, Handle, InputNode, Marker, MarkerDefinition, MarkerType, MiniMap, NodeRenderer, NodeResizer, NodeSelection, NodeToolbar, NodeWrapper, OutputNode, PanOnScrollMode, Pane, Panel, Position, ResizeControl, ResizeControlVariant, Selection, SelectionMode, SmoothStepEdge, SmoothStepEdgeInternal, SolidFlow, SolidFlowProvider, StepEdge, StepEdgeInternal, StraightEdge, StraightEdgeInternal, Viewport, ViewportPortal, Zoom, addEdge, connectionKey, createEdgeStore, createNodeStore, getBezierEdgeCenter, getBezierPath, getConnectedEdges, getEdgeCenter, getIncomers, getNodesBounds, getOutgoers, getSmoothStepPath, getStraightPath, getViewportForBounds, useColorMode, useConnection,
|
|
4500
|
+
export { Background, BaseEdge, BezierEdge, BezierEdgeInternal, ConnectionLine, ConnectionLineType, ConnectionMode, ControlButton, Controls, DefaultNode, EdgeLabel, EdgeLabelRenderer, EdgeReconnectAnchor, EdgeRenderer, EdgeToolbar, EdgeWrapper, GroupNode, Handle, InputNode, Marker, MarkerDefinition, MarkerType, MiniMap, MiniMapNode, NodeRenderer, NodeResizer, NodeSelection, NodeToolbar, NodeWrapper, OutputNode, PanOnScrollMode, Pane, Panel, Position, ResizeControl, ResizeControlVariant, Selection, SelectionMode, SmoothStepEdge, SmoothStepEdgeInternal, SolidFlow, SolidFlowProvider, StepEdge, StepEdgeInternal, StraightEdge, StraightEdgeInternal, Viewport, ViewportPortal, Zoom, addEdge, connectionKey, createEdgeStore, createNodeStore, getBezierEdgeCenter, getBezierPath, getConnectedEdges, getEdgeCenter, getIncomers, getNodesBounds, getOutgoers, getSmoothStepPath, getStraightPath, getViewportForBounds, useColorMode, useConnection, useEdgeId, useEdges, useInternalNode, useNodeConnections, useNodeId, useNodes, useNodesData, useNodesInitialized, useSolidFlow, useUpdateNodeInternals, useViewport, useViewportInitialized };
|