@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.jsx
CHANGED
|
@@ -5,9 +5,18 @@ import { Dynamic, Portal, isServer } from "@solidjs/web";
|
|
|
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
|
|
@@ -141,11 +150,13 @@ const getEdgeId = (connection) => {
|
|
|
141
150
|
size: 25,
|
|
142
151
|
reconnecting: !1,
|
|
143
152
|
style: {}
|
|
144
|
-
}), rest = omit(_props, "type", "class", "style", "position", "size", "reconnecting", "children"), { store, nodeLookup, edgeLookup, actions } = useInternalSolidFlow(), edgeId = useEdgeId(), [reconnecting, setReconnecting] = createSignal(!1);
|
|
153
|
+
}), rest = omit(_props, "type", "class", "style", "position", "size", "reconnecting", "onReconnectingChange", "children"), { store, nodeLookup, edgeLookup, actions } = useInternalSolidFlow(), edgeId = useEdgeId(), [reconnecting, setReconnecting] = createSignal(!1);
|
|
145
154
|
if (!edgeId()) throw Error("[solid-flow]: EdgeReconnectAnchor must be used within an Edge component");
|
|
146
|
-
let edge = () => edgeLookup[edgeId()],
|
|
155
|
+
let edge = () => edgeLookup[edgeId()], isReconnecting = () => _props.reconnecting || reconnecting(), setReconnectingState = (next) => {
|
|
156
|
+
setReconnecting(next), _props.onReconnectingChange?.(next);
|
|
157
|
+
}, onPointerDown = (event) => {
|
|
147
158
|
if (event.button !== 0) return;
|
|
148
|
-
|
|
159
|
+
setReconnectingState(!0), store.onReconnectStart?.(event, edge(), _props.type);
|
|
149
160
|
let opposite = _props.type === "target" ? {
|
|
150
161
|
nodeId: edge().source,
|
|
151
162
|
handleId: edge().sourceHandle ?? null,
|
|
@@ -169,7 +180,9 @@ const getEdgeId = (connection) => {
|
|
|
169
180
|
edgeUpdaterType: opposite.type,
|
|
170
181
|
cancelConnection: actions.cancelConnection,
|
|
171
182
|
panBy: actions.panBy,
|
|
172
|
-
updateConnection:
|
|
183
|
+
updateConnection: (connection) => {
|
|
184
|
+
actions.setConnection(connection), flush();
|
|
185
|
+
},
|
|
173
186
|
isValidConnection: store.isValidConnection,
|
|
174
187
|
onConnectStart: store.onConnectStart,
|
|
175
188
|
onConnectEnd: store.onConnectEnd,
|
|
@@ -181,7 +194,7 @@ const getEdgeId = (connection) => {
|
|
|
181
194
|
newEdge = store.onBeforeReconnect?.(newEdge, edge()) ?? newEdge, newEdge && actions.setEdges((edges) => edges.map((e) => e.id === edge().id ? newEdge : e)), store.onReconnect?.(edge(), connection);
|
|
182
195
|
},
|
|
183
196
|
onReconnectEnd: (event, connectionState) => {
|
|
184
|
-
|
|
197
|
+
setReconnectingState(!1), store.onReconnectEnd?.(event, edge(), opposite.type, connectionState);
|
|
185
198
|
},
|
|
186
199
|
getTransform: () => store.transform,
|
|
187
200
|
getFromHandle: () => store.connection.fromHandle,
|
|
@@ -204,7 +217,7 @@ const getEdgeId = (connection) => {
|
|
|
204
217
|
cursor: "move",
|
|
205
218
|
..._props.style
|
|
206
219
|
}}>
|
|
207
|
-
<Show when={!
|
|
220
|
+
<Show when={!isReconnecting()}>{_props.children}</Show>
|
|
208
221
|
</div>
|
|
209
222
|
</EdgeLabel>;
|
|
210
223
|
}, ARIA_NODE_DESC_KEY = "solid-flow__node-desc", ARIA_EDGE_DESC_KEY = "solid-flow__edge-desc", A11yDescriptions = () => {
|
|
@@ -227,7 +240,6 @@ const getEdgeId = (connection) => {
|
|
|
227
240
|
let [store, setStore] = createStore(edges);
|
|
228
241
|
return [store, setStore];
|
|
229
242
|
}, 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(() => {
|
|
230
|
-
if (!source.onlyRenderVisibleElements) return null;
|
|
231
243
|
let { width, height } = source;
|
|
232
244
|
if (!width || !height) return null;
|
|
233
245
|
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;
|
|
@@ -291,7 +303,7 @@ const getEdgeId = (connection) => {
|
|
|
291
303
|
selectNodesOnDrag: !0,
|
|
292
304
|
elevateNodesOnSelect: !0,
|
|
293
305
|
zIndexMode: "basic",
|
|
294
|
-
onlyRenderVisibleElements: !
|
|
306
|
+
onlyRenderVisibleElements: !1,
|
|
295
307
|
disableKeyboardA11y: !1,
|
|
296
308
|
defaultMarkerColor: "#b1b1b7",
|
|
297
309
|
ariaLiveMessage: "",
|
|
@@ -581,9 +593,17 @@ const createLayoutedEdges = (source) => {
|
|
|
581
593
|
return config().zIndexMode;
|
|
582
594
|
}
|
|
583
595
|
}), nodeLookup = new RecordMapFacade(internalNodes), initialViewport = getInitialViewport(_props.fitView, _props.initialViewport, _props.width ?? 0, _props.height ?? 0, nodeLookup), [viewportStore, setViewportStore] = createStore(_props.viewport ?? initialViewport);
|
|
584
|
-
createEffect(() =>
|
|
596
|
+
createEffect(() => {
|
|
597
|
+
let next = config().nodes;
|
|
598
|
+
for (let node of next);
|
|
599
|
+
return { next };
|
|
600
|
+
}, ({ next }) => {
|
|
585
601
|
setNodesStore(() => next);
|
|
586
|
-
}, { defer: !0 }), createEffect(() =>
|
|
602
|
+
}, { defer: !0 }), createEffect(() => {
|
|
603
|
+
let next = config().edges;
|
|
604
|
+
for (let edge of next);
|
|
605
|
+
return { next };
|
|
606
|
+
}, ({ next }) => {
|
|
587
607
|
setEdgesStore(() => next);
|
|
588
608
|
}, { defer: !0 }), createEffect(() => config().viewport, (next) => {
|
|
589
609
|
next && setViewportStore(() => next);
|
|
@@ -744,9 +764,6 @@ const createLayoutedEdges = (source) => {
|
|
|
744
764
|
return zoomActivationKeyPressed();
|
|
745
765
|
}
|
|
746
766
|
}), cullingViewport = createCullingViewport({
|
|
747
|
-
get onlyRenderVisibleElements() {
|
|
748
|
-
return store.onlyRenderVisibleElements;
|
|
749
|
-
},
|
|
750
767
|
get width() {
|
|
751
768
|
return store.width;
|
|
752
769
|
},
|
|
@@ -1572,16 +1589,30 @@ const Handle = (props) => {
|
|
|
1572
1589
|
};
|
|
1573
1590
|
}), dragging;
|
|
1574
1591
|
}, NodeIdContext = createContext(null);
|
|
1592
|
+
/**
|
|
1593
|
+
* Returns the id of the node this component is rendered inside. Available
|
|
1594
|
+
* anywhere in a custom node's subtree (provided by the node wrapper), so
|
|
1595
|
+
* nested components — like a custom `Handle` — can learn their host node
|
|
1596
|
+
* without prop drilling.
|
|
1597
|
+
*
|
|
1598
|
+
* @public
|
|
1599
|
+
* @returns a reactive accessor for the surrounding node's id
|
|
1600
|
+
*/
|
|
1575
1601
|
function useNodeId() {
|
|
1576
1602
|
let ctx = useContext(NodeIdContext);
|
|
1577
|
-
if (!ctx) throw Error("solid-flow:
|
|
1603
|
+
if (!ctx) throw Error("solid-flow: useNodeId must be called inside a node component (anywhere under a custom node's subtree)");
|
|
1578
1604
|
return ctx;
|
|
1579
1605
|
}
|
|
1580
1606
|
//#endregion
|
|
1581
1607
|
//#region src/components/node/NodeWrapper.tsx
|
|
1582
1608
|
/** Internal per-node wrapper: dragging, selection, a11y, measurement, viewport culling, and the dynamic node component. */
|
|
1583
1609
|
const NodeWrapper = (props) => {
|
|
1584
|
-
let { store, nodeLookup, parentIds, actions } = useInternalSolidFlow(), [nodeRef, setNodeRef] = createSignal(), node = () => nodeLookup.get(props.nodeId)
|
|
1610
|
+
let { store, nodeLookup, parentIds, actions } = useInternalSolidFlow(), [nodeRef, setNodeRef] = createSignal(), node = () => nodeLookup.get(props.nodeId);
|
|
1611
|
+
onCleanup(() => {
|
|
1612
|
+
let el = nodeRef();
|
|
1613
|
+
el && props.resizeObserver?.unobserve(el);
|
|
1614
|
+
});
|
|
1615
|
+
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 = () => {
|
|
1585
1616
|
let { x, y } = node().internals.positionAbsolute;
|
|
1586
1617
|
return `translate(${x}px, ${y}px)`;
|
|
1587
1618
|
}, sizeStyle = () => {
|
|
@@ -1950,16 +1981,28 @@ const ConnectionLine = (props) => {
|
|
|
1950
1981
|
</svg>
|
|
1951
1982
|
</Show>;
|
|
1952
1983
|
}, EdgeRenderer = (props) => {
|
|
1953
|
-
let { store } = useInternalSolidFlow()
|
|
1954
|
-
|
|
1984
|
+
let { store, actions } = useInternalSolidFlow(), [focusedEdgeId, setFocusedEdgeId] = createSignal(null), onFocusIn = (event) => {
|
|
1985
|
+
let edgeElement = event.target.closest("[data-id]");
|
|
1986
|
+
setFocusedEdgeId(edgeElement?.getAttribute("data-id") ?? null);
|
|
1987
|
+
};
|
|
1988
|
+
return <div class="solid-flow__edges" onFocusIn={onFocusIn} onFocusOut={() => setFocusedEdgeId(null)}>
|
|
1955
1989
|
<MarkerDefinition />
|
|
1956
1990
|
|
|
1957
1991
|
<For each={store.visibleEdgeIds}>
|
|
1958
|
-
{(edgeId) =>
|
|
1992
|
+
{(edgeId) => {
|
|
1993
|
+
let unmounted = createMemo(() => {
|
|
1994
|
+
if (!store.onlyRenderVisibleElements || focusedEdgeId() === edgeId) return !1;
|
|
1995
|
+
let edge = actions.getEdge(edgeId);
|
|
1996
|
+
return !!edge && isEdgeCulled(edge, store.cullingViewport);
|
|
1997
|
+
});
|
|
1998
|
+
return <Show when={!unmounted()}>
|
|
1999
|
+
<EdgeWrapper edgeId={edgeId} onEdgeClick={props.onEdgeClick} onEdgeContextMenu={props.onEdgeContextMenu} onEdgePointerEnter={props.onEdgePointerEnter} onEdgePointerLeave={props.onEdgePointerLeave} />
|
|
2000
|
+
</Show>;
|
|
2001
|
+
}}
|
|
1959
2002
|
</For>
|
|
1960
2003
|
</div>;
|
|
1961
2004
|
}, NodeRenderer = (props) => {
|
|
1962
|
-
let { actions, store } = useInternalSolidFlow(), resizeObserver = isServer ? void 0 : new ResizeObserver((entries) => {
|
|
2005
|
+
let { actions, store, nodeLookup } = useInternalSolidFlow(), resizeObserver = isServer ? void 0 : new ResizeObserver((entries) => {
|
|
1963
2006
|
actions.requestUpdateNodeInternals(entries.map((entry) => {
|
|
1964
2007
|
let id = entry.target.getAttribute("data-id");
|
|
1965
2008
|
return [id, {
|
|
@@ -1969,11 +2012,25 @@ const ConnectionLine = (props) => {
|
|
|
1969
2012
|
}];
|
|
1970
2013
|
}));
|
|
1971
2014
|
});
|
|
1972
|
-
|
|
2015
|
+
onCleanup(() => {
|
|
1973
2016
|
resizeObserver?.disconnect();
|
|
1974
|
-
})
|
|
2017
|
+
});
|
|
2018
|
+
let [focusedNodeId, setFocusedNodeId] = createSignal(null), onFocusIn = (event) => {
|
|
2019
|
+
let nodeElement = event.target.closest("[data-id]");
|
|
2020
|
+
setFocusedNodeId(nodeElement?.getAttribute("data-id") ?? null);
|
|
2021
|
+
};
|
|
2022
|
+
return <div class="solid-flow__container solid-flow__nodes" onFocusIn={onFocusIn} onFocusOut={() => setFocusedNodeId(null)}>
|
|
1975
2023
|
<For each={store.visibleNodeIds}>
|
|
1976
|
-
{(nodeId) =>
|
|
2024
|
+
{(nodeId) => {
|
|
2025
|
+
let unmounted = createMemo(() => {
|
|
2026
|
+
if (!store.onlyRenderVisibleElements || focusedNodeId() === nodeId) return !1;
|
|
2027
|
+
let node = nodeLookup.get(nodeId);
|
|
2028
|
+
return !!node && isNodeCulled(node, store.cullingViewport);
|
|
2029
|
+
});
|
|
2030
|
+
return <Show when={!unmounted()}>
|
|
2031
|
+
<NodeWrapper nodeId={nodeId} resizeObserver={resizeObserver} nodeClickDistance={props.nodeClickDistance} onNodeClick={props.onNodeClick} onNodePointerEnter={props.onNodePointerEnter} onNodePointerMove={props.onNodePointerMove} onNodePointerLeave={props.onNodePointerLeave} onNodeDrag={props.onNodeDrag} onNodeDragStart={props.onNodeDragStart} onNodeDragStop={props.onNodeDragStop} onNodeContextMenu={props.onNodeContextMenu} />
|
|
2032
|
+
</Show>;
|
|
2033
|
+
}}
|
|
1977
2034
|
</For>
|
|
1978
2035
|
</div>;
|
|
1979
2036
|
}, isSetEqual = (a, b) => {
|
|
@@ -2285,25 +2342,14 @@ const ConnectionLine = (props) => {
|
|
|
2285
2342
|
* `const { flow, commands } = useSolidFlow()`.
|
|
2286
2343
|
*
|
|
2287
2344
|
* @public
|
|
2288
|
-
* @returns the flow's read struct
|
|
2345
|
+
* @returns the flow's read struct and write surface
|
|
2289
2346
|
*/
|
|
2290
2347
|
function useSolidFlow() {
|
|
2291
|
-
let { flow, commands
|
|
2348
|
+
let { flow, commands } = useInternalSolidFlow();
|
|
2292
2349
|
return {
|
|
2293
2350
|
...commands,
|
|
2294
2351
|
flow,
|
|
2295
|
-
commands
|
|
2296
|
-
getInternalNode,
|
|
2297
|
-
getNode: (id) => getInternalNode(id)?.internals.userNode,
|
|
2298
|
-
getNodes: (ids) => ids ? ids.flatMap((id) => {
|
|
2299
|
-
let userNode = flow.internalNodes[id]?.internals.userNode;
|
|
2300
|
-
return userNode ? [userNode] : [];
|
|
2301
|
-
}) : [...flow.nodes],
|
|
2302
|
-
getEdge: (id) => edgeLookup[id],
|
|
2303
|
-
getEdges: (ids) => ids ? ids.flatMap((id) => edgeLookup[id] ? [edgeLookup[id]] : []) : [...flow.edges],
|
|
2304
|
-
getViewport: () => snapshot(store.viewport),
|
|
2305
|
-
getZoom: () => flow.viewport.zoom,
|
|
2306
|
-
getHandleConnections: ({ type, id, nodeId }) => Object.values(flow.connections[connectionKey(nodeId, type, id ?? null)] ?? {})
|
|
2352
|
+
commands
|
|
2307
2353
|
};
|
|
2308
2354
|
}
|
|
2309
2355
|
//#endregion
|
|
@@ -2534,19 +2580,6 @@ function useViewport() {
|
|
|
2534
2580
|
return () => flow.viewport;
|
|
2535
2581
|
}
|
|
2536
2582
|
//#endregion
|
|
2537
|
-
//#region src/hooks/useHandleEdgeSelect.ts
|
|
2538
|
-
/** Returns a callback applying edge-selection semantics for the given edge id. */
|
|
2539
|
-
function useHandleEdgeSelect() {
|
|
2540
|
-
let { store, edgeLookup, actions } = useInternalSolidFlow();
|
|
2541
|
-
return (id) => {
|
|
2542
|
-
let edge = edgeLookup[id];
|
|
2543
|
-
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({
|
|
2544
|
-
nodes: [],
|
|
2545
|
-
edges: [edge]
|
|
2546
|
-
}) : actions.addSelectedEdges([id]));
|
|
2547
|
-
};
|
|
2548
|
-
}
|
|
2549
|
-
//#endregion
|
|
2550
2583
|
//#region src/hooks/useInitialized.ts
|
|
2551
2584
|
/**
|
|
2552
2585
|
* Hook for seeing if all nodes have been measured.
|
|
@@ -2576,11 +2609,16 @@ function useViewportInitialized() {
|
|
|
2576
2609
|
//#endregion
|
|
2577
2610
|
//#region src/hooks/useInternalNode.ts
|
|
2578
2611
|
/**
|
|
2579
|
-
* Hook to get an internal node
|
|
2612
|
+
* Hook to get an internal node (the node enriched with measured dimensions,
|
|
2613
|
+
* absolute position, and z-order) by id.
|
|
2614
|
+
*
|
|
2615
|
+
* The id is an accessor (not a plain string) on purpose: passing a raw
|
|
2616
|
+
* reactive read like `props.nodeId` would capture the value once and silently
|
|
2617
|
+
* lose reactivity — `useInternalNode(() => props.nodeId)` keeps it live.
|
|
2580
2618
|
*
|
|
2581
2619
|
* @public
|
|
2582
|
-
* @param id - the node id
|
|
2583
|
-
* @returns an accessor with
|
|
2620
|
+
* @param id - a reactive accessor for the node id
|
|
2621
|
+
* @returns an accessor with the internal node, or undefined while absent
|
|
2584
2622
|
*/
|
|
2585
2623
|
function useInternalNode(id) {
|
|
2586
2624
|
let { flow } = useInternalSolidFlow();
|
|
@@ -2667,7 +2705,6 @@ const DotPattern = (props) => {
|
|
|
2667
2705
|
let _props = propDefaults(props, {
|
|
2668
2706
|
variant: "dots",
|
|
2669
2707
|
gap: 20,
|
|
2670
|
-
size: 1,
|
|
2671
2708
|
lineWidth: 1,
|
|
2672
2709
|
style: {}
|
|
2673
2710
|
}), { 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];
|
|
@@ -2763,8 +2800,8 @@ const DotPattern = (props) => {
|
|
|
2763
2800
|
borderRadius: 5,
|
|
2764
2801
|
width: 0,
|
|
2765
2802
|
height: 0
|
|
2766
|
-
}), style = () => Object.entries({
|
|
2767
|
-
fill:
|
|
2803
|
+
}), fill = () => _props.color ?? _props.style?.background ?? _props.style?.["background-color"], style = () => Object.entries({
|
|
2804
|
+
fill: fill(),
|
|
2768
2805
|
stroke: _props.strokeColor,
|
|
2769
2806
|
"stroke-width": _props.strokeWidth
|
|
2770
2807
|
}).filter(([_, value]) => value !== void 0).reduce((acc, [key, value]) => (acc[key] = value, acc), {});
|
|
@@ -2772,7 +2809,7 @@ const DotPattern = (props) => {
|
|
|
2772
2809
|
"solid-flow__minimap-node",
|
|
2773
2810
|
{ selected: !!_props.selected },
|
|
2774
2811
|
_props.class
|
|
2775
|
-
]} x={_props.x} y={_props.y} rx={_props.borderRadius} ry={_props.borderRadius} width={_props.width} height={_props.height} shape-rendering={_props.shapeRendering} style={style()} />;
|
|
2812
|
+
]} x={_props.x} y={_props.y} rx={_props.borderRadius} ry={_props.borderRadius} width={_props.width} height={_props.height} shape-rendering={_props.shapeRendering} style={style()} onClick={_props.onClick ? (event) => _props.onClick(event, _props.id) : void 0} />;
|
|
2776
2813
|
}, getAttrFunction = (func) => func instanceof Function ? func : () => func, MiniMap = (props) => {
|
|
2777
2814
|
let { store, nodeLookup } = useInternalSolidFlow(), _props = propDefaults(props, {
|
|
2778
2815
|
position: "bottom-right",
|
|
@@ -2785,7 +2822,7 @@ const DotPattern = (props) => {
|
|
|
2785
2822
|
nodeBorderRadius: 5,
|
|
2786
2823
|
nodeStrokeWidth: 2,
|
|
2787
2824
|
style: {}
|
|
2788
|
-
}), 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 = () => ({
|
|
2825
|
+
}), 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 = () => ({
|
|
2789
2826
|
x: -store.viewport.x / store.viewport.zoom,
|
|
2790
2827
|
y: -store.viewport.y / store.viewport.zoom,
|
|
2791
2828
|
width: store.width / store.viewport.zoom,
|
|
@@ -2810,7 +2847,7 @@ const DotPattern = (props) => {
|
|
|
2810
2847
|
<Show when={store.panZoom}>
|
|
2811
2848
|
{(panZoom) => {
|
|
2812
2849
|
let [ref, setRef] = createSignal(), [minimap, setMinimap] = createSignal();
|
|
2813
|
-
|
|
2850
|
+
createEffect(() => ({
|
|
2814
2851
|
el: ref(),
|
|
2815
2852
|
panZoom: panZoom()
|
|
2816
2853
|
}), ({ el, panZoom }) => {
|
|
@@ -2837,7 +2874,19 @@ const DotPattern = (props) => {
|
|
|
2837
2874
|
}
|
|
2838
2875
|
}), ({ instance, options }) => {
|
|
2839
2876
|
instance?.update(options);
|
|
2840
|
-
})
|
|
2877
|
+
});
|
|
2878
|
+
let onSvgClick = (event) => {
|
|
2879
|
+
if (!_props.onClick) return;
|
|
2880
|
+
let [x, y] = minimap()?.pointer(event) ?? [0, 0];
|
|
2881
|
+
_props.onClick(event, {
|
|
2882
|
+
x,
|
|
2883
|
+
y
|
|
2884
|
+
});
|
|
2885
|
+
}, onSvgNodeClick = (event, nodeId) => {
|
|
2886
|
+
let node = nodeLookup.get(nodeId)?.internals.userNode;
|
|
2887
|
+
node && _props.onNodeClick?.(event, node);
|
|
2888
|
+
};
|
|
2889
|
+
return <svg ref={setRef} width={_props.width} height={_props.height} viewBox={`${getX()} ${getY()} ${getViewboxWidth()} ${getViewboxHeight()}`} class="solid-flow__minimap-svg" role="img" aria-labelledby={labelledBy()} onClick={_props.onClick ? onSvgClick : void 0} style={{
|
|
2841
2890
|
"--xy-minimap-mask-background-color-props": _props.maskColor,
|
|
2842
2891
|
"--xy-minimap-mask-stroke-color-props": _props.maskStrokeColor,
|
|
2843
2892
|
"--xy-minimap-mask-stroke-width-props": strokeWidth()
|
|
@@ -2847,7 +2896,7 @@ const DotPattern = (props) => {
|
|
|
2847
2896
|
{(nodeId) => {
|
|
2848
2897
|
let node = createMemo(() => nodeLookup.get(nodeId())), nodeVisible = () => !!(node() && nodeHasDimensions(node()) && !node().hidden);
|
|
2849
2898
|
return <Show when={nodeVisible() && getNodeDimensions(node())}>
|
|
2850
|
-
{(nodeDimensions) => <MiniMapNode x={node().internals.positionAbsolute.x} y={node().internals.positionAbsolute.y} borderRadius={_props.nodeBorderRadius} strokeWidth={_props.nodeStrokeWidth} shapeRendering={shapeRendering()} width={nodeDimensions().width} height={nodeDimensions().height} selected={node().selected} color={nodeColorFunc()?.call(null, node())} strokeColor={nodeStrokeColorFunc().call(null, node())} class={nodeClassFunc().call(null, node())} />}
|
|
2899
|
+
{(nodeDimensions) => <Dynamic component={_props.nodeComponent ?? MiniMapNode} id={nodeId()} x={node().internals.positionAbsolute.x} y={node().internals.positionAbsolute.y} borderRadius={_props.nodeBorderRadius} strokeWidth={_props.nodeStrokeWidth} shapeRendering={shapeRendering()} width={nodeDimensions().width} height={nodeDimensions().height} selected={node().selected} color={nodeColorFunc()?.call(null, node())} strokeColor={nodeStrokeColorFunc().call(null, node())} class={nodeClassFunc().call(null, node())} style={node().style} onClick={_props.onNodeClick ? onSvgNodeClick : void 0} />}
|
|
2851
2900
|
</Show>;
|
|
2852
2901
|
}}
|
|
2853
2902
|
</For>
|
|
@@ -2964,7 +3013,7 @@ const DotPattern = (props) => {
|
|
|
2964
3013
|
</EdgeLabel>
|
|
2965
3014
|
</Show>;
|
|
2966
3015
|
}, NodeToolbar = (props) => {
|
|
2967
|
-
let { store } = useInternalSolidFlow(), {
|
|
3016
|
+
let { store } = useInternalSolidFlow(), { flow, getNodesBounds } = useSolidFlow(), _props = propDefaults(props, {
|
|
2968
3017
|
offset: 10,
|
|
2969
3018
|
position: "top",
|
|
2970
3019
|
align: "center",
|
|
@@ -2973,7 +3022,7 @@ const DotPattern = (props) => {
|
|
|
2973
3022
|
let id = useContext(NodeIdContext);
|
|
2974
3023
|
return id ? id() : "";
|
|
2975
3024
|
}, toolbarNodes = () => (Array.isArray(_props.nodeId) ? _props.nodeId : [_props.nodeId ?? ctxNodeId()]).reduce((res, nodeId) => {
|
|
2976
|
-
let node =
|
|
3025
|
+
let node = flow.internalNodes[nodeId];
|
|
2977
3026
|
return node && res.push(node), res;
|
|
2978
3027
|
}, []), transform = () => {
|
|
2979
3028
|
let nodeRect = getNodesBounds(toolbarNodes());
|
|
@@ -2981,7 +3030,7 @@ const DotPattern = (props) => {
|
|
|
2981
3030
|
}, zIndex = () => {
|
|
2982
3031
|
let nodes = toolbarNodes();
|
|
2983
3032
|
return nodes.length === 0 ? 1 : Math.max(...nodes.map((node) => (node.internals.z || 5) + 1));
|
|
2984
|
-
}, selectedNodesCount = () =>
|
|
3033
|
+
}, selectedNodesCount = () => flow.selection.nodes.length, isActive = () => {
|
|
2985
3034
|
let nodes = toolbarNodes();
|
|
2986
3035
|
return typeof _props.isVisible == "boolean" ? _props.isVisible : nodes.length === 1 && !!nodes[0].selected && selectedNodesCount() === 1;
|
|
2987
3036
|
}, showPortal = () => !!(store.domNode && isActive() && toolbarNodes().length > 0);
|
|
@@ -2999,4 +3048,4 @@ const DotPattern = (props) => {
|
|
|
2999
3048
|
</Show>;
|
|
3000
3049
|
}, SelectionMode = SelectionMode$1, getEdgeCenter = getEdgeCenter$1, getBezierEdgeCenter = getBezierEdgeCenter$1;
|
|
3001
3050
|
//#endregion
|
|
3002
|
-
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,
|
|
3051
|
+
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 };
|
package/dist/styles/index.css
CHANGED
package/package.json
CHANGED