@dschz/solid-flow 0.1.3 → 0.1.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.
@@ -1,207 +1,4470 @@
1
- import{For as Ts}from"solid-js";import{createContext as ur,useContext as yr}from"solid-js";var xo=ur();function ke(){let e=yr(xo);if(!e)throw new Error("solid-flow: Your application must be wrapped with <SolidFlow> in order to invoke useEdgeId");return e}import{createContext as as,useContext as ls}from"solid-js";import{ReactiveMap as ze}from"@solid-primitives/map";import{createMediaQuery as Bi}from"@solid-primitives/media";import{addEdge as Vi,calculateNodePosition as Ki,clampPosition as Xi,fitViewport as Fi,getEdgePosition as Yi,getElevatedEdgeZIndex as Wi,getInternalNodesBounds as Zi,getNodeDimensions as $i,getNodePositionWithOrigin as Ui,getViewportForBounds as Ji,infiniteExtent as Gi,initialConnection as Yo,isCoordinateExtent as ji,isEdgeVisible as qi,mergeAriaLabelConfig as Qi,panBy as es,pointToRendererPoint as ln,snapPosition as os,updateAbsolutePositions as ts,updateNodeInternals as ns}from"@xyflow/system";import{batch as Ce,createComputed as Re,createEffect as Te,createMemo as Ue,createSignal as re,mapArray as cn,mergeProps as pn,onCleanup as gn,untrack as rs}from"solid-js";import{produce as ve}from"solid-js/store";import Tr from"clsx";import{mergeProps as vr,Show as Ut,splitProps as Mr}from"solid-js";import xr from"clsx";import{mergeProps as wr,splitProps as Cr}from"solid-js";import{isEdgeBase as fr,isNodeBase as hr}from"@xyflow/system";import{createMemo as Zt,createSignal as Sr}from"solid-js";import{createStore as Nr}from"solid-js/store";var wo=e=>hr(e),$t=e=>fr(e),J=e=>e===void 0?void 0:`${e}px`,Xe={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}};function se(e){let o=Zt(()=>Sr(e()));return[()=>o()[0](),S=>o()[1](S)]}function Fe(e){let o=Zt(()=>{let[t,N]=Nr(e());return{get:t,set:N}});return{get(){return o().get},get set(){return o().set}}}import{Show as Pr}from"solid-js";import{Portal as Er}from"solid-js/web";var Co=e=>{let{store:o}=z(),t=()=>o.domNode?.querySelector(".solid-flow__edge-labels");return<Pr when={t()}>{N=><Er mount={N()}>{e.children}</Er>}</Pr>};var De=e=>{let o=wr({x:0,y:0,selectEdgeOnClick:!1,transparent:!1,style:{}},e),[t,N]=Cr(o,["x","y","width","height","selectEdgeOnClick","transparent","children","class","style"]),{actions:S}=z(),P=ke(),x=()=>S.getEdge(P())?.zIndex;return<Co>
2
- <div role="button"tabIndex={-1}class={xr("solid-flow__edge-label",{transparent:t.transparent},t.class)}style={{"pointer-events":"all",width:J(t.width),height:J(t.height),transform:`translate(-50%, -50%) translate(${t.x}px,${t.y}px)`,cursor:t.selectEdgeOnClick?"pointer":void 0,"z-index":x(),...t.style}}onClick={()=>{t.selectEdgeOnClick&&S.handleEdgeSelection(P())}}{...N}>
3
- {t.children}
1
+ // src/components/container/EdgeRenderer.tsx
2
+ import { For as For2 } from "solid-js";
3
+
4
+ // src/components/contexts/edgeId.tsx
5
+ import { createContext, useContext } from "solid-js";
6
+ var EdgeIdContext = createContext();
7
+ function useEdgeId() {
8
+ const ctx = useContext(EdgeIdContext);
9
+ if (!ctx) {
10
+ throw new Error(
11
+ "solid-flow: Your application must be wrapped with <SolidFlow> in order to invoke useEdgeId"
12
+ );
13
+ }
14
+ return ctx;
15
+ }
16
+
17
+ // src/components/contexts/flow.tsx
18
+ import { createContext as createContext4, useContext as useContext4 } from "solid-js";
19
+
20
+ // src/data/createSolidFlow.tsx
21
+ import { ReactiveMap } from "@solid-primitives/map";
22
+ import { createMediaQuery } from "@solid-primitives/media";
23
+ import {
24
+ addEdge as systemAddEdge,
25
+ calculateNodePosition,
26
+ clampPosition as clampPosition2,
27
+ fitViewport,
28
+ getEdgePosition,
29
+ getElevatedEdgeZIndex,
30
+ getInternalNodesBounds,
31
+ getNodeDimensions as getNodeDimensions2,
32
+ getNodePositionWithOrigin as getNodePositionWithOrigin2,
33
+ getViewportForBounds,
34
+ infiniteExtent as infiniteExtent3,
35
+ initialConnection,
36
+ isCoordinateExtent as isCoordinateExtent2,
37
+ isEdgeVisible,
38
+ mergeAriaLabelConfig,
39
+ panBy as panBySystem,
40
+ pointToRendererPoint,
41
+ snapPosition,
42
+ updateAbsolutePositions,
43
+ updateNodeInternals as systemUpdateNodeInternals
44
+ } from "@xyflow/system";
45
+ import {
46
+ batch as batch2,
47
+ createComputed,
48
+ createEffect as createEffect4,
49
+ createMemo as createMemo5,
50
+ createSignal as createSignal5,
51
+ mapArray,
52
+ mergeProps as mergeProps8,
53
+ onCleanup as onCleanup2,
54
+ untrack
55
+ } from "solid-js";
56
+ import { produce } from "solid-js/store";
57
+
58
+ // src/components/graph/edge/BaseEdge.tsx
59
+ import clsx2 from "clsx";
60
+ import { mergeProps as mergeProps2, Show as Show2, splitProps as splitProps2 } from "solid-js";
61
+
62
+ // src/components/graph/edge/EdgeLabel.tsx
63
+ import clsx from "clsx";
64
+ import { mergeProps, splitProps } from "solid-js";
65
+
66
+ // src/utils.ts
67
+ import { isEdgeBase, isNodeBase } from "@xyflow/system";
68
+ import { createMemo, createSignal } from "solid-js";
69
+ import { createStore } from "solid-js/store";
70
+ var isNode = (element) => isNodeBase(element);
71
+ var isEdge = (element) => isEdgeBase(element);
72
+ var toPxString = (value) => value === void 0 ? void 0 : `${value}px`;
73
+ var ARROW_KEY_DIFFS = {
74
+ ArrowUp: { x: 0, y: -1 },
75
+ ArrowDown: { x: 0, y: 1 },
76
+ ArrowLeft: { x: -1, y: 0 },
77
+ ArrowRight: { x: 1, y: 0 }
78
+ };
79
+ function createWritable(accessor) {
80
+ const signal = createMemo(() => createSignal(accessor()));
81
+ const get = () => signal()[0]();
82
+ const set = (v) => signal()[1](v);
83
+ return [get, set];
84
+ }
85
+ function createWritableStore(accessor) {
86
+ const storeMemo = createMemo(() => {
87
+ const [get, set] = createStore(accessor());
88
+ return { get, set };
89
+ });
90
+ return {
91
+ get() {
92
+ return storeMemo().get;
93
+ },
94
+ get set() {
95
+ return storeMemo().set;
96
+ }
97
+ };
98
+ }
99
+
100
+ // src/components/graph/edge/EdgeLabelRenderer.tsx
101
+ import { Show } from "solid-js";
102
+ import { Portal } from "solid-js/web";
103
+ var EdgeLabelRenderer = (props) => {
104
+ const { store } = useInternalSolidFlow();
105
+ const labelNode = () => store.domNode?.querySelector(".solid-flow__edge-labels");
106
+ return <Show when={labelNode()}>{(root) => <Portal mount={root()}>{props.children}</Portal>}</Show>;
107
+ };
108
+
109
+ // src/components/graph/edge/EdgeLabel.tsx
110
+ var EdgeLabel = (props) => {
111
+ const _props = mergeProps(
112
+ {
113
+ x: 0,
114
+ y: 0,
115
+ selectEdgeOnClick: false,
116
+ transparent: false,
117
+ style: {}
118
+ },
119
+ props
120
+ );
121
+ const [local, rest] = splitProps(_props, [
122
+ "x",
123
+ "y",
124
+ "width",
125
+ "height",
126
+ "selectEdgeOnClick",
127
+ "transparent",
128
+ "children",
129
+ "class",
130
+ "style"
131
+ ]);
132
+ const { actions } = useInternalSolidFlow();
133
+ const id = useEdgeId();
134
+ const zIndex = () => actions.getEdge(id())?.zIndex;
135
+ return <EdgeLabelRenderer>
136
+ <div
137
+ role="button"
138
+ tabIndex={-1}
139
+ class={clsx("solid-flow__edge-label", { transparent: local.transparent }, local.class)}
140
+ style={{
141
+ // TODO: Add hideOnSSR
142
+ "pointer-events": "all",
143
+ width: toPxString(local.width),
144
+ height: toPxString(local.height),
145
+ transform: `translate(-50%, -50%) translate(${local.x}px,${local.y}px)`,
146
+ cursor: local.selectEdgeOnClick ? "pointer" : void 0,
147
+ "z-index": zIndex(),
148
+ ...local.style
149
+ }}
150
+ onClick={() => {
151
+ if (local.selectEdgeOnClick) actions.handleEdgeSelection(id());
152
+ }}
153
+ {...rest}
154
+ >
155
+ {local.children}
4
156
  </div>
5
- </Co>};var Q=e=>{let o=vr({interactionWidth:20},e),[t,N]=Mr(o,["class","style","path","interactionWidth","label","labelStyle","labelX","labelY","markerStart","markerEnd"]);return<>
6
- <path d={t.path}class={Tr(["solid-flow__edge-path",t.class])}marker-start={t.markerStart}marker-end={t.markerEnd}fill="none"style={t.style}{...N}/>
7
-
8
- <Ut when={t.interactionWidth>0}>
9
- <path d={t.path}stroke-opacity={0}stroke-width={t.interactionWidth}fill="none"class="solid-flow__edge-interaction"/>
10
- </Ut>
11
-
12
- <Ut when={t.label}>
13
- <De x={t.labelX}y={t.labelY}style={t.labelStyle}>
14
- {t.label}
15
- </De>
16
- </Ut>
17
- </>};import{getBezierPath as Ir}from"@xyflow/system";var kr=e=>{let o=()=>{let[t,N,S]=Ir({sourceX:e.sourceX,sourceY:e.sourceY,targetX:e.targetX,targetY:e.targetY,sourcePosition:e.sourcePosition,targetPosition:e.targetPosition,curvature:e.pathOptions?.curvature});return{path:t,labelX:N,labelY:S}};return<Q id={e.id}path={o().path}labelX={o().labelX}labelY={o().labelY}label={e.label}labelStyle={e.labelStyle}markerStart={e.markerStart}markerEnd={e.markerEnd}interactionWidth={e.interactionWidth}style={e.style}/>};import{getBezierPath as Dr}from"@xyflow/system";var To=e=>{let o=()=>{let[t,N,S]=Dr({sourceX:e.sourceX,sourceY:e.sourceY,targetX:e.targetX,targetY:e.targetY,sourcePosition:e.sourcePosition,targetPosition:e.targetPosition});return{path:t,labelX:N,labelY:S}};return<Q path={o().path}labelX={o().labelX}labelY={o().labelY}label={e.label}labelStyle={e.labelStyle}markerStart={e.markerStart}markerEnd={e.markerEnd}interactionWidth={e.interactionWidth}style={e.style}/>};import{XYHandle as Or}from"@xyflow/system";import zr from"clsx";import{createSignal as Rr,mergeProps as Ar,Show as _r,splitProps as Lr}from"solid-js";var Hr=e=>{let o=Ar({size:25,reconnecting:!1,style:{}},e),[t,N]=Lr(o,["type","class","style","position","size","reconnecting","children"]),{store:S,nodeLookup:P,edgeLookup:x,actions:b}=z(),C=ke(),[T,v]=Rr(!1);if(!C())throw new Error("[solid-flow]: EdgeReconnectAnchor must be used within an Edge component");let E=()=>x.get(C()),w=I=>{if(I.button!==0)return;v(!0),S.onReconnectStart?.(I,E(),t.type);let D=t.type==="target"?{nodeId:E().source,handleId:E().sourceHandle??null,type:"source"}:{nodeId:E().target,handleId:E().targetHandle??null,type:"target"};Or.onPointerDown(I,{lib:S.lib,flowId:S.id,domNode:S.domNode,nodeId:D.nodeId,handleId:D.handleId,autoPanOnConnect:S.autoPanOnConnect,connectionMode:S.connectionMode,connectionRadius:S.connectionRadius,nodeLookup:P,isTarget:D.type==="target",edgeUpdaterType:D.type,cancelConnection:b.cancelConnection,panBy:b.panBy,updateConnection:b.setConnection,isValidConnection:S.isValidConnection,onConnectStart:S.onConnectStart,onConnectEnd:S.onConnectEnd,onConnect:k=>{let R={...E(),...k};R=S.onBeforeReconnect?.(R,E())??R,R&&b.setEdges(Y=>Y.map(H=>H.id===E().id?R:H)),S.onReconnect?.(E(),k)},onReconnectEnd:(k,R)=>{v(!1),S.onReconnectEnd?.(k,E(),D.type,R)},getTransform:()=>S.transform,getFromHandle:()=>S.connection.fromHandle,autoPanSpeed:S.autoPanSpeed,dragThreshold:S.connectionDragThreshold,handleDomNode:I.currentTarget})};return<De x={t.position?.x}y={t.position?.y}style={t.style}{...N}>
18
- <div onPointerDown={w}class={zr("solid-flow__edgeupdater",`solid-flow__edgeupdater-${t.type}`,S.noPanClass,t.class)}style={{width:J(t.size),height:J(t.size),background:"transparent",border:"none",cursor:"move",...t.style}}>
19
- <_r when={!T()}>{t.children}</_r>
157
+ </EdgeLabelRenderer>;
158
+ };
159
+
160
+ // src/components/graph/edge/BaseEdge.tsx
161
+ var BaseEdge = (props) => {
162
+ const _props = mergeProps2(
163
+ {
164
+ interactionWidth: 20
165
+ },
166
+ props
167
+ );
168
+ const [local, rest] = splitProps2(_props, [
169
+ "class",
170
+ "style",
171
+ "path",
172
+ "interactionWidth",
173
+ "label",
174
+ "labelStyle",
175
+ "labelX",
176
+ "labelY",
177
+ "markerStart",
178
+ "markerEnd"
179
+ ]);
180
+ return <>
181
+ <path
182
+ d={local.path}
183
+ class={clsx2(["solid-flow__edge-path", local.class])}
184
+ marker-start={local.markerStart}
185
+ marker-end={local.markerEnd}
186
+ fill="none"
187
+ style={local.style}
188
+ {...rest}
189
+ />
190
+
191
+ <Show2 when={local.interactionWidth > 0}>
192
+ <path
193
+ d={local.path}
194
+ stroke-opacity={0}
195
+ stroke-width={local.interactionWidth}
196
+ fill="none"
197
+ class="solid-flow__edge-interaction"
198
+ />
199
+ </Show2>
200
+
201
+ <Show2 when={local.label}>
202
+ <EdgeLabel x={local.labelX} y={local.labelY} style={local.labelStyle}>
203
+ {local.label}
204
+ </EdgeLabel>
205
+ </Show2>
206
+ </>;
207
+ };
208
+
209
+ // src/components/graph/edge/BezierEdge.tsx
210
+ import { getBezierPath } from "@xyflow/system";
211
+ var BezierEdge = (props) => {
212
+ const pathData = () => {
213
+ const [path, labelX, labelY] = getBezierPath({
214
+ sourceX: props.sourceX,
215
+ sourceY: props.sourceY,
216
+ targetX: props.targetX,
217
+ targetY: props.targetY,
218
+ sourcePosition: props.sourcePosition,
219
+ targetPosition: props.targetPosition,
220
+ curvature: props.pathOptions?.curvature
221
+ });
222
+ return { path, labelX, labelY };
223
+ };
224
+ return <BaseEdge
225
+ id={props.id}
226
+ path={pathData().path}
227
+ labelX={pathData().labelX}
228
+ labelY={pathData().labelY}
229
+ label={props.label}
230
+ labelStyle={props.labelStyle}
231
+ markerStart={props.markerStart}
232
+ markerEnd={props.markerEnd}
233
+ interactionWidth={props.interactionWidth}
234
+ style={props.style}
235
+ />;
236
+ };
237
+
238
+ // src/components/graph/edge/BezierEdgeInternal.tsx
239
+ import { getBezierPath as getBezierPath2 } from "@xyflow/system";
240
+ var BezierEdgeInternal = (props) => {
241
+ const pathData = () => {
242
+ const [path, labelX, labelY] = getBezierPath2({
243
+ sourceX: props.sourceX,
244
+ sourceY: props.sourceY,
245
+ targetX: props.targetX,
246
+ targetY: props.targetY,
247
+ sourcePosition: props.sourcePosition,
248
+ targetPosition: props.targetPosition
249
+ });
250
+ return { path, labelX, labelY };
251
+ };
252
+ return <BaseEdge
253
+ path={pathData().path}
254
+ labelX={pathData().labelX}
255
+ labelY={pathData().labelY}
256
+ label={props.label}
257
+ labelStyle={props.labelStyle}
258
+ markerStart={props.markerStart}
259
+ markerEnd={props.markerEnd}
260
+ interactionWidth={props.interactionWidth}
261
+ style={props.style}
262
+ />;
263
+ };
264
+
265
+ // src/components/graph/edge/EdgeReconnectAnchor.tsx
266
+ import { XYHandle } from "@xyflow/system";
267
+ import clsx3 from "clsx";
268
+ import { createSignal as createSignal2, mergeProps as mergeProps3, Show as Show3, splitProps as splitProps3 } from "solid-js";
269
+ var EdgeReconnectAnchor = (props) => {
270
+ const _props = mergeProps3(
271
+ {
272
+ size: 25,
273
+ reconnecting: false,
274
+ style: {}
275
+ },
276
+ props
277
+ );
278
+ const [local, rest] = splitProps3(_props, [
279
+ "type",
280
+ "class",
281
+ "style",
282
+ "position",
283
+ "size",
284
+ "reconnecting",
285
+ "children"
286
+ ]);
287
+ const { store, nodeLookup, edgeLookup, actions } = useInternalSolidFlow();
288
+ const edgeId = useEdgeId();
289
+ const [reconnecting, setReconnecting] = createSignal2(false);
290
+ if (!edgeId()) {
291
+ throw new Error("[solid-flow]: EdgeReconnectAnchor must be used within an Edge component");
292
+ }
293
+ const edge = () => edgeLookup.get(edgeId());
294
+ const onPointerDown = (event) => {
295
+ if (event.button !== 0) {
296
+ return;
297
+ }
298
+ setReconnecting(true);
299
+ store.onReconnectStart?.(event, edge(), local.type);
300
+ const opposite = local.type === "target" ? {
301
+ nodeId: edge().source,
302
+ handleId: edge().sourceHandle ?? null,
303
+ type: "source"
304
+ } : {
305
+ nodeId: edge().target,
306
+ handleId: edge().targetHandle ?? null,
307
+ type: "target"
308
+ };
309
+ XYHandle.onPointerDown(event, {
310
+ lib: store.lib,
311
+ flowId: store.id,
312
+ domNode: store.domNode,
313
+ nodeId: opposite.nodeId,
314
+ handleId: opposite.handleId,
315
+ autoPanOnConnect: store.autoPanOnConnect,
316
+ connectionMode: store.connectionMode,
317
+ connectionRadius: store.connectionRadius,
318
+ nodeLookup,
319
+ isTarget: opposite.type === "target",
320
+ edgeUpdaterType: opposite.type,
321
+ cancelConnection: actions.cancelConnection,
322
+ panBy: actions.panBy,
323
+ updateConnection: actions.setConnection,
324
+ isValidConnection: store.isValidConnection,
325
+ onConnectStart: store.onConnectStart,
326
+ onConnectEnd: store.onConnectEnd,
327
+ onConnect: (connection) => {
328
+ let newEdge = { ...edge(), ...connection };
329
+ newEdge = store.onBeforeReconnect?.(newEdge, edge()) ?? newEdge;
330
+ if (newEdge) {
331
+ actions.setEdges((edges) => edges.map((e) => e.id === edge().id ? newEdge : e));
332
+ }
333
+ store.onReconnect?.(edge(), connection);
334
+ },
335
+ onReconnectEnd: (event2, connectionState) => {
336
+ setReconnecting(false);
337
+ store.onReconnectEnd?.(event2, edge(), opposite.type, connectionState);
338
+ },
339
+ getTransform: () => store.transform,
340
+ getFromHandle: () => store.connection.fromHandle,
341
+ autoPanSpeed: store.autoPanSpeed,
342
+ dragThreshold: store.connectionDragThreshold,
343
+ handleDomNode: event.currentTarget
344
+ });
345
+ };
346
+ return <EdgeLabel x={local.position?.x} y={local.position?.y} style={local.style} {...rest}>
347
+ <div
348
+ onPointerDown={onPointerDown}
349
+ class={clsx3(
350
+ "solid-flow__edgeupdater",
351
+ `solid-flow__edgeupdater-${local.type}`,
352
+ store.noPanClass,
353
+ local.class
354
+ )}
355
+ style={{
356
+ width: toPxString(local.size),
357
+ height: toPxString(local.size),
358
+ background: "transparent",
359
+ border: "none",
360
+ cursor: "move",
361
+ ...local.style
362
+ }}
363
+ >
364
+ <Show3 when={!reconnecting()}>{local.children}</Show3>
20
365
  </div>
21
- </De>};import{elementSelectionKeys as Vr,getMarkerId as Gt}from"@xyflow/system";import Kr from"clsx";import{Show as Xr}from"solid-js";import{Dynamic as Fr}from"solid-js/web";import{Show as Br}from"solid-js";var Ye="solid-flow__node-desc",We="solid-flow__edge-desc",Jt="solid-flow__aria-live";var Mo=()=>{let{store:e}=z();return<>
22
- <div id={`${Ye}-${e.id}`}class="a11y-hidden">
23
- {e.disableKeyboardA11y?e.ariaLabelConfig["node.a11yDescription.default"]:e.ariaLabelConfig["node.a11yDescription.keyboardDisabled"]}
366
+ </EdgeLabel>;
367
+ };
368
+
369
+ // src/components/graph/edge/EdgeWrapper.tsx
370
+ import { elementSelectionKeys, getMarkerId } from "@xyflow/system";
371
+ import clsx4 from "clsx";
372
+ import { Show as Show5 } from "solid-js";
373
+ import { Dynamic } from "solid-js/web";
374
+
375
+ // src/components/accessibility/A11yDescriptions.tsx
376
+ import { Show as Show4 } from "solid-js";
377
+
378
+ // src/components/accessibility/constants.ts
379
+ var ARIA_NODE_DESC_KEY = "solid-flow__node-desc";
380
+ var ARIA_EDGE_DESC_KEY = "solid-flow__edge-desc";
381
+ var ARIA_LIVE_MESSAGE = "solid-flow__aria-live";
382
+
383
+ // src/components/accessibility/A11yDescriptions.tsx
384
+ var A11yDescriptions = () => {
385
+ const { store } = useInternalSolidFlow();
386
+ return <>
387
+ <div id={`${ARIA_NODE_DESC_KEY}-${store.id}`} class="a11y-hidden">
388
+ {store.disableKeyboardA11y ? store.ariaLabelConfig["node.a11yDescription.default"] : store.ariaLabelConfig["node.a11yDescription.keyboardDisabled"]}
24
389
  </div>
25
- <div id={`${We}-${e.id}`}class="a11y-hidden">
26
- {e.ariaLabelConfig["edge.a11yDescription.default"]}
390
+ <div id={`${ARIA_EDGE_DESC_KEY}-${store.id}`} class="a11y-hidden">
391
+ {store.ariaLabelConfig["edge.a11yDescription.default"]}
27
392
  </div>
28
393
 
29
- <Br when={!e.disableKeyboardA11y}>
30
- <div id={`${Jt}-${e.id}`}aria-live="assertive"aria-atomic="true"class="a11y-live-msg">
31
- {e.ariaLiveMessage}
394
+ <Show4 when={!store.disableKeyboardA11y}>
395
+ <div
396
+ id={`${ARIA_LIVE_MESSAGE}-${store.id}`}
397
+ aria-live="assertive"
398
+ aria-atomic="true"
399
+ class="a11y-live-msg"
400
+ >
401
+ {store.ariaLiveMessage}
32
402
  </div>
33
- </Br>
34
- </>};var Io=e=>{let o,{store:t,actions:N}=z(),S=()=>e.edgeId,P=()=>N.getEdge(S()),x=()=>P().type??"default",b=()=>P().selectable??t.elementsSelectable,C=()=>P().focusable??t.edgesFocusable,T=()=>t.edgeTypes[x()],v=()=>P().markerStart?`url('#${Gt(P().markerStart,t.id)}')`:void 0,E=()=>P().markerEnd?`url('#${Gt(P().markerEnd,t.id)}')`:void 0,w=R=>{b()&&N.handleEdgeSelection(S()),e.onEdgeClick?.({edge:P(),event:R})},I=(R,Y)=>{({contextmenu:e.onEdgeContextMenu,pointerenter:e.onEdgePointerEnter,pointerleave:e.onEdgePointerLeave})[Y]?.({edge:P(),event:R})},D=R=>{if(t.disableKeyboardA11y||!Vr.includes(R.key)||!b())return;R.key==="Escape"?(o?.blur(),N.unselectNodesAndEdges({edges:[P()]})):N.addSelectedEdges([P().id])},k=()=>P().ariaLabel??`Edge from ${P().source} to ${P().target}`;return<xo.Provider value={S}>
35
- <Xr when={!P().hidden}>
36
- <svg class="solid-flow__edge-wrapper"style={{"z-index":P().zIndex}}>
37
- <g ref={o}data-id={P().id}tabIndex={C()?0:void 0}role={P().ariaRole??(C()?"group":"img")}aria-label={k()}aria-roledescription="edge"aria-describedby={C()?`${We}-${t.id}`:void 0}class={Kr("solid-flow__edge",`solid-flow__edge-${x()}`,{animated:P().animated,selected:P().selected,selectable:b()},P().class)}onClick={w}onKeyDown={R=>C()&&D(R)}onContextMenu={R=>I(R,"contextmenu")}onPointerEnter={R=>I(R,"pointerenter")}onPointerLeave={R=>I(R,"pointerleave")}{...P().domAttributes}>
38
- <Fr component={T()}id={P().id}source={P().source}target={P().target}sourceX={P().sourceX}sourceY={P().sourceY}targetX={P().targetX}targetY={P().targetY}sourcePosition={P().sourcePosition}targetPosition={P().targetPosition}animated={P().animated}selected={P().selected}label={P().label}labelStyle={P().labelStyle}data={P().data}style={P().style}interactionWidth={P().interactionWidth}selectable={b()}deletable={P().deletable??!0}type={x()}sourceHandleId={P().sourceHandle}targetHandleId={P().targetHandle}markerStart={v()}markerEnd={E()}/>
403
+ </Show4>
404
+ </>;
405
+ };
406
+
407
+ // src/components/graph/edge/EdgeWrapper.tsx
408
+ var EdgeWrapper = (props) => {
409
+ let edgeRef;
410
+ const { store, actions } = useInternalSolidFlow();
411
+ const edgeId = () => props.edgeId;
412
+ const edge = () => actions.getEdge(edgeId());
413
+ const edgeType = () => edge().type ?? "default";
414
+ const selectable = () => edge().selectable ?? store.elementsSelectable;
415
+ const focusable = () => edge().focusable ?? store.edgesFocusable;
416
+ const edgeComponent = () => store.edgeTypes[edgeType()];
417
+ const markerStartUrl = () => edge().markerStart ? `url('#${getMarkerId(edge().markerStart, store.id)}')` : void 0;
418
+ const markerEndUrl = () => edge().markerEnd ? `url('#${getMarkerId(edge().markerEnd, store.id)}')` : void 0;
419
+ const onClick = (event) => {
420
+ if (selectable()) {
421
+ actions.handleEdgeSelection(edgeId());
422
+ }
423
+ props.onEdgeClick?.({ edge: edge(), event });
424
+ };
425
+ const onPointerEvent = (event, type) => {
426
+ const handlers = {
427
+ contextmenu: props.onEdgeContextMenu,
428
+ pointerenter: props.onEdgePointerEnter,
429
+ pointerleave: props.onEdgePointerLeave
430
+ };
431
+ handlers[type]?.({ edge: edge(), event });
432
+ };
433
+ const onKeyDown = (event) => {
434
+ if (store.disableKeyboardA11y || !elementSelectionKeys.includes(event.key) || !selectable()) {
435
+ return;
436
+ }
437
+ const unselect = event.key === "Escape";
438
+ if (unselect) {
439
+ edgeRef?.blur();
440
+ actions.unselectNodesAndEdges({ edges: [edge()] });
441
+ } else {
442
+ actions.addSelectedEdges([edge().id]);
443
+ }
444
+ };
445
+ const ariaLabel = () => edge().ariaLabel ?? `Edge from ${edge().source} to ${edge().target}`;
446
+ return <EdgeIdContext.Provider value={edgeId}>
447
+ <Show5 when={!edge().hidden}>
448
+ <svg class="solid-flow__edge-wrapper" style={{ "z-index": edge().zIndex }}>
449
+ <g
450
+ ref={edgeRef}
451
+ data-id={edge().id}
452
+ tabIndex={focusable() ? 0 : void 0}
453
+ role={edge().ariaRole ?? (focusable() ? "group" : "img")}
454
+ aria-label={ariaLabel()}
455
+ aria-roledescription="edge"
456
+ aria-describedby={focusable() ? `${ARIA_EDGE_DESC_KEY}-${store.id}` : void 0}
457
+ class={clsx4(
458
+ "solid-flow__edge",
459
+ `solid-flow__edge-${edgeType()}`,
460
+ {
461
+ animated: edge().animated,
462
+ selected: edge().selected,
463
+ selectable: selectable()
464
+ },
465
+ edge().class
466
+ )}
467
+ onClick={onClick}
468
+ onKeyDown={(e) => focusable() && onKeyDown(e)}
469
+ onContextMenu={(e) => onPointerEvent(e, "contextmenu")}
470
+ onPointerEnter={(e) => onPointerEvent(e, "pointerenter")}
471
+ onPointerLeave={(e) => onPointerEvent(e, "pointerleave")}
472
+ {...edge().domAttributes}
473
+ >
474
+ <Dynamic
475
+ component={edgeComponent()}
476
+ id={edge().id}
477
+ source={edge().source}
478
+ target={edge().target}
479
+ sourceX={edge().sourceX}
480
+ sourceY={edge().sourceY}
481
+ targetX={edge().targetX}
482
+ targetY={edge().targetY}
483
+ sourcePosition={edge().sourcePosition}
484
+ targetPosition={edge().targetPosition}
485
+ animated={edge().animated}
486
+ selected={edge().selected}
487
+ label={edge().label}
488
+ labelStyle={edge().labelStyle}
489
+ data={edge().data}
490
+ style={edge().style}
491
+ interactionWidth={edge().interactionWidth}
492
+ selectable={selectable()}
493
+ deletable={edge().deletable ?? true}
494
+ type={edgeType()}
495
+ sourceHandleId={edge().sourceHandle}
496
+ targetHandleId={edge().targetHandle}
497
+ markerStart={markerStartUrl()}
498
+ markerEnd={markerEndUrl()}
499
+ />
39
500
  </g>
40
501
  </svg>
41
- </Xr>
42
- </xo.Provider>};import{getSmoothStepPath as Yr}from"@xyflow/system";import{createMemo as Wr}from"solid-js";var Zr=e=>{let o=Wr(()=>{let[t,N,S]=Yr({sourceX:e.sourceX,sourceY:e.sourceY,targetX:e.targetX,targetY:e.targetY,sourcePosition:e.sourcePosition,targetPosition:e.targetPosition,borderRadius:e.pathOptions?.borderRadius,offset:e.pathOptions?.offset});return{path:t,labelX:N,labelY:S}});return<Q id={e.id}path={o().path}labelX={o().labelX}labelY={o().labelY}label={e.label}labelStyle={e.labelStyle}markerStart={e.markerStart}markerEnd={e.markerEnd}interactionWidth={e.interactionWidth}style={e.style}/>};import{getSmoothStepPath as $r}from"@xyflow/system";var ko=e=>{let o=()=>{let[t,N,S]=$r({sourceX:e.sourceX,sourceY:e.sourceY,targetX:e.targetX,targetY:e.targetY,sourcePosition:e.sourcePosition,targetPosition:e.targetPosition});return{path:t,labelX:N,labelY:S}};return<Q path={o().path}labelX={o().labelX}labelY={o().labelY}label={e.label}labelStyle={e.labelStyle}markerStart={e.markerStart}markerEnd={e.markerEnd}interactionWidth={e.interactionWidth}style={e.style}/>};import{getSmoothStepPath as Ur}from"@xyflow/system";import{createMemo as Jr}from"solid-js";var Gr=e=>{let o=Jr(()=>{let[t,N,S]=Ur({sourceX:e.sourceX,sourceY:e.sourceY,targetX:e.targetX,targetY:e.targetY,sourcePosition:e.sourcePosition,targetPosition:e.targetPosition,borderRadius:0,offset:e.pathOptions?.offset});return{path:t,labelX:N,labelY:S}});return<Q id={e.id}path={o().path}labelX={o().labelX}labelY={o().labelY}label={e.label}labelStyle={e.labelStyle}markerStart={e.markerStart}markerEnd={e.markerEnd}interactionWidth={e.interactionWidth}style={e.style}/>};import{getSmoothStepPath as jr}from"@xyflow/system";var Do=e=>{let o=()=>{let[t,N,S]=jr({sourceX:e.sourceX,sourceY:e.sourceY,targetX:e.targetX,targetY:e.targetY,sourcePosition:e.sourcePosition,targetPosition:e.targetPosition,borderRadius:0});return{path:t,labelX:N,labelY:S}};return<Q path={o().path}labelX={o().labelX}labelY={o().labelY}label={e.label}labelStyle={e.labelStyle}markerStart={e.markerStart}markerEnd={e.markerEnd}interactionWidth={e.interactionWidth}style={e.style}/>};import{getStraightPath as qr}from"@xyflow/system";import{createMemo as Qr}from"solid-js";var ei=e=>{let o=Qr(()=>{let[t,N,S]=qr({sourceX:e.sourceX,sourceY:e.sourceY,targetX:e.targetX,targetY:e.targetY});return{path:t,labelX:N,labelY:S}});return<Q id={e.id}path={o().path}labelX={o().labelX}labelY={o().labelY}label={e.label}labelStyle={e.labelStyle}markerStart={e.markerStart}markerEnd={e.markerEnd}interactionWidth={e.interactionWidth}style={e.style}/>};import{getStraightPath as oi}from"@xyflow/system";var Oo=e=>{let o=()=>{let[t,N,S]=oi({sourceX:e.sourceX,sourceY:e.sourceY,targetX:e.targetX,targetY:e.targetY});return{path:t,labelX:N,labelY:S}};return<Q path={o().path}labelX={o().labelX}labelY={o().labelY}label={e.label}labelStyle={e.labelStyle}markerStart={e.markerStart}markerEnd={e.markerEnd}interactionWidth={e.interactionWidth}style={e.style}/>};import{mergeProps as pi}from"solid-js";import{areConnectionMapsEqual as ri,getHostForElement as ii,handleConnectionChange as Qt,XYHandle as en}from"@xyflow/system";import si from"clsx";import{createEffect as di,mergeProps as ai,splitProps as li}from"solid-js";import{unwrap as ci}from"solid-js/store";import{getNodesInside as rp}from"@xyflow/system";var jt=e=>{let{source:o,sourceHandle:t,target:N,targetHandle:S}=e;return`xy-edge__${o}${t||""}-${N}${S||""}`};import{createContext as ti,useContext as ni}from"solid-js";var zo=ti();function qt(){let e=ni(zo);if(!e)throw new Error("solid-flow: Your application must be wrapped with <SolidFlow> in order to invoke useNodeConnectable");return e}var Se=e=>{let o=ai({id:null,type:"source",position:"top",isConnectableStart:!0,isConnectableEnd:!0},e),{store:t,nodeLookup:N,connectionLookup:S,actions:P}=z(),[x,b]=li(o,["id","type","position","isConnectable","isConnectableStart","isConnectableEnd","isValidConnection","onConnect","onDisconnect","children","class","style"]),C=Oe(),T=qt(),v=()=>x.isConnectable??T(),E=()=>x.type==="target",w=()=>x.id??null,I=()=>!!t.connection.fromHandle,D=()=>t.connection.fromHandle&&t.connection.fromHandle.nodeId===C()&&t.connection.fromHandle.type===x.type&&t.connection.fromHandle.id===w(),k=()=>t.connection.toHandle&&t.connection.toHandle.nodeId===C()&&t.connection.toHandle.type===x.type&&t.connection.toHandle.id===w(),R=()=>t.connectionMode==="strict"?t.connection.fromHandle?.type!==x.type:C()!==t.connection.fromHandle?.nodeId||w()!==t.connection.fromHandle?.id,Y=()=>!!(k()&&t.connection.isValid),H=null,_;di(()=>{if(!x.onConnect&&!x.onDisconnect)return;let U=`${C()}-${x.type}${x.id?`-${x.id}`:""}`;if(_=S.get(U),H&&!ri(_,H)){let G=_??new Map;Qt(H,G,e.onDisconnect),Qt(G,H,e.onConnect)}H=_??new Map});let $=U=>{let G={...U,id:jt(U)},O=t.onBeforeConnect?.(G)??G;P.addEdge(O),t.onConnect?.(G)},ee=U=>{en.onPointerDown(U,{handleId:w(),nodeId:C(),isTarget:E(),connectionRadius:t.connectionRadius,domNode:t.domNode,nodeLookup:N,connectionMode:t.connectionMode,lib:t.lib,autoPanOnConnect:t.autoPanOnConnect,flowId:t.id,isValidConnection:x.isValidConnection??t.isValidConnection,updateConnection:P.setConnection,cancelConnection:P.cancelConnection,panBy:P.panBy,onConnect:$,onConnectStart:(G,O)=>{t.onConnectStart?.(G,{nodeId:O.nodeId,handleId:O.handleId,handleType:O.handleType})},onConnectEnd:t.onConnectEnd,getTransform:()=>t.transform,getFromHandle:()=>t.connection.fromHandle,autoPanSpeed:t.autoPanSpeed,dragThreshold:t.connectionDragThreshold,handleDomNode:U.currentTarget})},ie=U=>{if(!C()||!t.clickConnectStartHandle&&!x.isConnectableStart)return;if(!t.clickConnectStartHandle){t.onClickConnectStart?.(U,{nodeId:C(),handleId:w(),handleType:x.type}),P.setClickConnectStartHandle({nodeId:C(),type:x.type,id:w()});return}let G=ii(U.target),O=x.isValidConnection??t.isValidConnection,{connection:F,isValid:K}=en.isValid(U,{handle:{nodeId:C(),id:w(),type:x.type},connectionMode:t.connectionMode,fromNodeId:t.clickConnectStartHandle.nodeId,fromHandleId:t.clickConnectStartHandle.id??null,fromType:t.clickConnectStartHandle.type,isValidConnection:O,flowId:t.id,doc:G,lib:t.lib,nodeLookup:N});K&&F&&$(F);let Z=structuredClone(ci(t.connection));delete Z.inProgress,Z.toPosition=Z.toHandle?Z.toHandle.position:null,t.onClickConnectEnd?.(U,Z),P.setClickConnectStartHandle(void 0)},de=()=>v()&&(!I()||R())&&(I()||t.clickConnectStartHandle?x.isConnectableEnd:x.isConnectableStart);return<div role="button"aria-label={t.ariaLabelConfig["handle.ariaLabel"]}tabIndex={-1}data-handleid={w()}data-nodeid={C()}data-handlepos={x.position}data-id={`${t.id}-${C()}-${x.id||null}-${x.type}`}onClick={t.clickConnect?ie:void 0}onPointerDown={ee}style={x.style}class={si("solid-flow__handle",`solid-flow__handle-${x.position}`,t.noDragClass,t.noPanClass,x.class,{valid:Y(),connectingto:k(),connectingfrom:D(),source:!E(),target:E(),connectablestart:o.isConnectableStart,connectableend:o.isConnectableEnd,connectable:v(),connectionindicator:de()})}{...b}>
43
- {x.children}
44
- </div>};var Ro=e=>{let o=pi({targetPosition:"top",sourcePosition:"bottom"},e);return<>
45
- <Se type="target"position={o.targetPosition}isConnectable={o.isConnectable}/>
46
- {e.data.label}
47
- <Se type="source"position={o.sourcePosition}isConnectable={o.isConnectable}/>
48
- </>};var Ao=e=><div style={{position:"absolute",left:0,top:0,width:J(e.width),height:J(e.height)}}/>;import{mergeProps as gi}from"solid-js";var _o=e=>{let o=gi({sourcePosition:"bottom"},e);return<>
49
- {e.data?.label}
50
- <Se type="source"position={o.sourcePosition}isConnectable={o.isConnectable}/>
51
- </>};import{elementSelectionKeys as bi,getNodesInside as Ei,isInputDOMNode as xi,nodeHasDimensions as on}from"@xyflow/system";import wi from"clsx";import{batch as Ci,createEffect as Lo,createSignal as Ti,Show as Mi}from"solid-js";import{Dynamic as Ii}from"solid-js/web";import{XYDrag as mi}from"@xyflow/system";import{createEffect as ui,createSignal as yi,onCleanup as fi,onMount as hi}from"solid-js";var Si=(e,o)=>{let{store:t,nodeLookup:N,actions:S}=z(),[P,x]=yi(!1);return hi(()=>{let{onDrag:b,onDragStart:C,onDragStop:T,onNodeMouseDown:v}=o(),E=mi({onDrag:b,onDragStart:(I,D,k,R)=>{x(!0),C?.(I,D,k,R)},onDragStop:(I,D,k,R)=>{x(!1),T?.(I,D,k,R)},onNodeMouseDown:v,getStoreItems:()=>({nodes:t.nodes,nodeLookup:N,edges:t.edges,nodeExtent:t.nodeExtent,snapGrid:t.snapGrid??[0,0],snapToGrid:!!t.snapGrid,autoPanSpeed:t.autoPanSpeed,nodeOrigin:t.nodeOrigin,multiSelectionActive:t.multiselectionKeyPressed,domNode:t.domNode,transform:t.transform,autoPanOnNodeDrag:t.autoPanOnNodeDrag,nodesDraggable:t.nodesDraggable,selectNodesOnDrag:t.selectNodesOnDrag,nodeDragThreshold:t.nodeDragThreshold,unselectNodesAndEdges:S.unselectNodesAndEdges,updateNodePositions:S.updateNodePositions,panBy:S.panBy})});function w(I,D){if(D.disabled){E.destroy();return}E.update({domNode:I,nodeId:D.nodeId,noDragClassName:D.noDragClass,handleSelector:D.handleSelector,isSelectable:D.isSelectable,nodeClickDistance:D.nodeClickDistance})}ui(()=>{w(e(),o())}),fi(()=>{E.destroy()})}),P},Ze=Si;import{createContext as Ni,useContext as Pi}from"solid-js";var Ne=Ni();function Oe(){let e=Pi(Ne);if(!e)throw new Error("solid-flow: Your application must be wrapped with <SolidFlow> in order to invoke useNodeId");return e}var Ho=e=>{let{store:o,nodeLookup:t,parentLookup:N,actions:S}=z(),[P,x]=Ti(),b=()=>t.get(e.nodeId),C=()=>b().id,T=()=>b().type??"default",v=()=>b().deletable??!0,E=()=>b().selectable??o.elementsSelectable,w=()=>b().focusable??o.nodesFocusable,I=()=>b().draggable??o.nodesDraggable,D=()=>b().connectable??o.nodesConnectable,k=()=>b().internals.userNode,R=()=>T()in o.nodeTypes,Y=()=>o.nodeTypes[T()],H=()=>N.has(b().id),_=()=>{let{x:O,y:F}=b().internals.positionAbsolute;return`translate(${O}px, ${F}px)`},$=()=>{let O=b().width??b().initialWidth,F=b().height??b().initialHeight;return{...b().style,...O?{width:J(O)}:{},...F?{height:J(F)}:{}}},ee=()=>({"z-index":b().internals.z,transform:_(),visibility:on(b())?"visible":"hidden",...$(),...b().style??{}});Lo(()=>{R()}),Lo(O=>O&&O.sourcePosition===b().sourcePosition&&O.targetPosition===b().targetPosition&&O.nodeType===T()?O:(S.requestUpdateNodeInternals([[b().id,{id:b().id,nodeElement:P(),force:!0}]]),{nodeType:T(),sourcePosition:b().sourcePosition,targetPosition:b().targetPosition})),Lo(O=>{let F=P();return F===O&&on(b())?O:(O&&e.resizeObserver.unobserve(O),F&&e.resizeObserver.observe(F),F)});let ie=O=>{E()&&(!o.selectNodesOnDrag||!I()||o.nodeDragThreshold>0)&&S.handleNodeSelection(b().id),e.onNodeClick?.({node:k(),event:O})},de=O=>{if(xi(O)||o.disableKeyboardA11y)return;if(bi.includes(O.key)&&E()){S.handleNodeSelection(b().id,O.key==="Escape",P());return}let F=Xe[O.key];I()&&b().selected&&F&&Ci(()=>{O.preventDefault(),S.setAriaLiveMessage(o.ariaLabelConfig["node.a11yDescription.ariaLiveMessage"]({direction:O.key.replace("Arrow","").toLowerCase(),x:~~b().internals.positionAbsolute.x,y:~~b().internals.positionAbsolute.y})),S.moveSelectedNodes(F,O.shiftKey?4:1)})},U=()=>{if(o.disableKeyboardA11y||!o.autoPanOnNodeFocus||!P()?.matches(":focus-visible"))return;let{width:O,height:F,viewport:K}=o;Ei(new Map([[b().id,b()]]),{x:0,y:0,width:O,height:F},[K.x,K.y,K.zoom],!0).length>0||S.setCenter(b().position.x+(b().measured.width??0)/2,b().position.y+(b().measured.height??0)/2,{zoom:K.zoom})},G=Ze(P,()=>({nodeId:b().id,isSelectable:E(),disabled:!I(),handleSelector:b().dragHandle,noDragClass:o.noDragClass,nodeClickDistance:e.nodeClickDistance,onNodeMouseDown:S.handleNodeSelection,onDrag:(O,F,K,Z)=>{e.onNodeDrag?.({event:O,targetNode:K,nodes:Z})},onDragStart:(O,F,K,Z)=>{e.onNodeDragStart?.({event:O,targetNode:K,nodes:Z})},onDragStop:(O,F,K,Z)=>{e.onNodeDragStop?.({event:O,targetNode:K,nodes:Z})}}));return<Mi when={!b().hidden}>
52
- <div ref={x}data-id={b().id}class={wi("solid-flow__node",`solid-flow__node-${T()}`,{connectable:D(),draggable:I(),dragging:G(),nopan:I(),parent:H(),selectable:E(),selected:b().selected},b().class)}style={ee()}onClick={ie}onPointerEnter={O=>e.onNodePointerEnter?.({node:k(),event:O})}onPointerLeave={O=>e.onNodePointerLeave?.({node:k(),event:O})}onPointerMove={O=>e.onNodePointerMove?.({node:k(),event:O})}onContextMenu={O=>e.onNodeContextMenu?.({node:k(),event:O})}onKeyDown={O=>w()&&de(O)}onFocus={()=>w()&&U()}tabIndex={w()?0:void 0}role={b().ariaRole??(w()?"group":void 0)}aria-roledescription="node"aria-describedby={o.disableKeyboardA11y?void 0:`${Ye}-${o.id}`}{...b().domAttributes}>
53
- <Ne.Provider value={C}>
54
- <zo.Provider value={D}>
55
- <Ii component={Y()}data={b().data}id={b().id}selected={!!b().selected}selectable={E()}deletable={v()}sourcePosition={b().sourcePosition}targetPosition={b().targetPosition}zIndex={b().internals.z}dragging={G()}draggable={I()}dragHandle={b().dragHandle}parentId={b().parentId}type={T()}isConnectable={D()}positionAbsoluteX={b().internals.positionAbsolute.x}positionAbsoluteY={b().internals.positionAbsolute.y}width={b().width}height={b().height}/>
56
- </zo.Provider>
57
- </Ne.Provider>
502
+ </Show5>
503
+ </EdgeIdContext.Provider>;
504
+ };
505
+
506
+ // src/components/graph/edge/SmoothStepEdge.tsx
507
+ import { getSmoothStepPath } from "@xyflow/system";
508
+ import { createMemo as createMemo2 } from "solid-js";
509
+ var SmoothStepEdge = (props) => {
510
+ const pathData = createMemo2(() => {
511
+ const [path, labelX, labelY] = getSmoothStepPath({
512
+ sourceX: props.sourceX,
513
+ sourceY: props.sourceY,
514
+ targetX: props.targetX,
515
+ targetY: props.targetY,
516
+ sourcePosition: props.sourcePosition,
517
+ targetPosition: props.targetPosition,
518
+ borderRadius: props.pathOptions?.borderRadius,
519
+ offset: props.pathOptions?.offset
520
+ });
521
+ return { path, labelX, labelY };
522
+ });
523
+ return <BaseEdge
524
+ id={props.id}
525
+ path={pathData().path}
526
+ labelX={pathData().labelX}
527
+ labelY={pathData().labelY}
528
+ label={props.label}
529
+ labelStyle={props.labelStyle}
530
+ markerStart={props.markerStart}
531
+ markerEnd={props.markerEnd}
532
+ interactionWidth={props.interactionWidth}
533
+ style={props.style}
534
+ />;
535
+ };
536
+
537
+ // src/components/graph/edge/SmoothStepEdgeInternal.tsx
538
+ import { getSmoothStepPath as getSmoothStepPath2 } from "@xyflow/system";
539
+ var SmoothStepEdgeInternal = (props) => {
540
+ const pathData = () => {
541
+ const [path, labelX, labelY] = getSmoothStepPath2({
542
+ sourceX: props.sourceX,
543
+ sourceY: props.sourceY,
544
+ targetX: props.targetX,
545
+ targetY: props.targetY,
546
+ sourcePosition: props.sourcePosition,
547
+ targetPosition: props.targetPosition
548
+ });
549
+ return { path, labelX, labelY };
550
+ };
551
+ return <BaseEdge
552
+ path={pathData().path}
553
+ labelX={pathData().labelX}
554
+ labelY={pathData().labelY}
555
+ label={props.label}
556
+ labelStyle={props.labelStyle}
557
+ markerStart={props.markerStart}
558
+ markerEnd={props.markerEnd}
559
+ interactionWidth={props.interactionWidth}
560
+ style={props.style}
561
+ />;
562
+ };
563
+
564
+ // src/components/graph/edge/StepEdge.tsx
565
+ import { getSmoothStepPath as getSmoothStepPath3 } from "@xyflow/system";
566
+ import { createMemo as createMemo3 } from "solid-js";
567
+ var StepEdge = (props) => {
568
+ const pathData = createMemo3(() => {
569
+ const [path, labelX, labelY] = getSmoothStepPath3({
570
+ sourceX: props.sourceX,
571
+ sourceY: props.sourceY,
572
+ targetX: props.targetX,
573
+ targetY: props.targetY,
574
+ sourcePosition: props.sourcePosition,
575
+ targetPosition: props.targetPosition,
576
+ borderRadius: 0,
577
+ offset: props.pathOptions?.offset
578
+ });
579
+ return { path, labelX, labelY };
580
+ });
581
+ return <BaseEdge
582
+ id={props.id}
583
+ path={pathData().path}
584
+ labelX={pathData().labelX}
585
+ labelY={pathData().labelY}
586
+ label={props.label}
587
+ labelStyle={props.labelStyle}
588
+ markerStart={props.markerStart}
589
+ markerEnd={props.markerEnd}
590
+ interactionWidth={props.interactionWidth}
591
+ style={props.style}
592
+ />;
593
+ };
594
+
595
+ // src/components/graph/edge/StepEdgeInternal.tsx
596
+ import { getSmoothStepPath as getSmoothStepPath4 } from "@xyflow/system";
597
+ var StepEdgeInternal = (props) => {
598
+ const pathData = () => {
599
+ const [path, labelX, labelY] = getSmoothStepPath4({
600
+ sourceX: props.sourceX,
601
+ sourceY: props.sourceY,
602
+ targetX: props.targetX,
603
+ targetY: props.targetY,
604
+ sourcePosition: props.sourcePosition,
605
+ targetPosition: props.targetPosition,
606
+ borderRadius: 0
607
+ });
608
+ return { path, labelX, labelY };
609
+ };
610
+ return <BaseEdge
611
+ path={pathData().path}
612
+ labelX={pathData().labelX}
613
+ labelY={pathData().labelY}
614
+ label={props.label}
615
+ labelStyle={props.labelStyle}
616
+ markerStart={props.markerStart}
617
+ markerEnd={props.markerEnd}
618
+ interactionWidth={props.interactionWidth}
619
+ style={props.style}
620
+ />;
621
+ };
622
+
623
+ // src/components/graph/edge/StraightEdge.tsx
624
+ import { getStraightPath } from "@xyflow/system";
625
+ import { createMemo as createMemo4 } from "solid-js";
626
+ var StraightEdge = (props) => {
627
+ const pathData = createMemo4(() => {
628
+ const [path, labelX, labelY] = getStraightPath({
629
+ sourceX: props.sourceX,
630
+ sourceY: props.sourceY,
631
+ targetX: props.targetX,
632
+ targetY: props.targetY
633
+ });
634
+ return { path, labelX, labelY };
635
+ });
636
+ return <BaseEdge
637
+ id={props.id}
638
+ path={pathData().path}
639
+ labelX={pathData().labelX}
640
+ labelY={pathData().labelY}
641
+ label={props.label}
642
+ labelStyle={props.labelStyle}
643
+ markerStart={props.markerStart}
644
+ markerEnd={props.markerEnd}
645
+ interactionWidth={props.interactionWidth}
646
+ style={props.style}
647
+ />;
648
+ };
649
+
650
+ // src/components/graph/edge/StraightEdgeInternal.tsx
651
+ import { getStraightPath as getStraightPath2 } from "@xyflow/system";
652
+ var StraightEdgeInternal = (props) => {
653
+ const pathData = () => {
654
+ const [path, labelX, labelY] = getStraightPath2({
655
+ sourceX: props.sourceX,
656
+ sourceY: props.sourceY,
657
+ targetX: props.targetX,
658
+ targetY: props.targetY
659
+ });
660
+ return { path, labelX, labelY };
661
+ };
662
+ return <BaseEdge
663
+ path={pathData().path}
664
+ labelX={pathData().labelX}
665
+ labelY={pathData().labelY}
666
+ label={props.label}
667
+ labelStyle={props.labelStyle}
668
+ markerStart={props.markerStart}
669
+ markerEnd={props.markerEnd}
670
+ interactionWidth={props.interactionWidth}
671
+ style={props.style}
672
+ />;
673
+ };
674
+
675
+ // src/components/graph/node/DefaultNode.tsx
676
+ import { mergeProps as mergeProps5 } from "solid-js";
677
+
678
+ // src/components/graph/handle/Handle.tsx
679
+ import {
680
+ areConnectionMapsEqual,
681
+ getHostForElement,
682
+ handleConnectionChange,
683
+ XYHandle as XYHandle2
684
+ } from "@xyflow/system";
685
+ import clsx5 from "clsx";
686
+ import { createEffect, mergeProps as mergeProps4, splitProps as splitProps4 } from "solid-js";
687
+ import { unwrap } from "solid-js/store";
688
+
689
+ // src/data/utils.ts
690
+ import {
691
+ getNodesInside
692
+ } from "@xyflow/system";
693
+ var getEdgeId = (connection) => {
694
+ const { source, sourceHandle, target, targetHandle } = connection;
695
+ return `xy-edge__${source}${sourceHandle || ""}-${target}${targetHandle || ""}`;
696
+ };
697
+
698
+ // src/components/contexts/nodeConnectable.tsx
699
+ import { createContext as createContext2, useContext as useContext2 } from "solid-js";
700
+ var NodeConnectableContext = createContext2();
701
+ function useNodeConnectable() {
702
+ const ctx = useContext2(NodeConnectableContext);
703
+ if (!ctx) {
704
+ throw new Error(
705
+ "solid-flow: Your application must be wrapped with <SolidFlow> in order to invoke useNodeConnectable"
706
+ );
707
+ }
708
+ return ctx;
709
+ }
710
+
711
+ // src/components/graph/handle/Handle.tsx
712
+ var Handle = (props) => {
713
+ const _props = mergeProps4(
714
+ {
715
+ id: null,
716
+ type: "source",
717
+ position: "top",
718
+ isConnectableStart: true,
719
+ isConnectableEnd: true
720
+ },
721
+ props
722
+ );
723
+ const { store, nodeLookup, connectionLookup, actions } = useInternalSolidFlow();
724
+ const [local, rest] = splitProps4(_props, [
725
+ "id",
726
+ "type",
727
+ "position",
728
+ "isConnectable",
729
+ "isConnectableStart",
730
+ "isConnectableEnd",
731
+ "isValidConnection",
732
+ "onConnect",
733
+ "onDisconnect",
734
+ "children",
735
+ "class",
736
+ "style"
737
+ ]);
738
+ const nodeId = useNodeId();
739
+ const nodeConnectable = useNodeConnectable();
740
+ const connectable = () => local.isConnectable ?? nodeConnectable();
741
+ const isTarget = () => local.type === "target";
742
+ const handleId = () => local.id ?? null;
743
+ const connectionInProcess = () => Boolean(store.connection.fromHandle);
744
+ const connectingFrom = () => store.connection.fromHandle && store.connection.fromHandle.nodeId === nodeId() && store.connection.fromHandle.type === local.type && store.connection.fromHandle.id === handleId();
745
+ const connectingTo = () => store.connection.toHandle && store.connection.toHandle.nodeId === nodeId() && store.connection.toHandle.type === local.type && store.connection.toHandle.id === handleId();
746
+ const isPossibleTargetHandle = () => store.connectionMode === "strict" ? store.connection.fromHandle?.type !== local.type : nodeId() !== store.connection.fromHandle?.nodeId || handleId() !== store.connection.fromHandle?.id;
747
+ const valid = () => Boolean(connectingTo() && store.connection.isValid);
748
+ let prevConnections = null;
749
+ let connections;
750
+ createEffect(() => {
751
+ if (!local.onConnect && !local.onDisconnect) return;
752
+ const conectionKey = `${nodeId()}-${local.type}${local.id ? `-${local.id}` : ""}`;
753
+ connections = connectionLookup.get(conectionKey);
754
+ if (prevConnections && !areConnectionMapsEqual(connections, prevConnections)) {
755
+ const _connections = connections ?? /* @__PURE__ */ new Map();
756
+ handleConnectionChange(prevConnections, _connections, props.onDisconnect);
757
+ handleConnectionChange(_connections, prevConnections, props.onConnect);
758
+ }
759
+ prevConnections = connections ?? /* @__PURE__ */ new Map();
760
+ });
761
+ const onConnectExtended = (connection) => {
762
+ const handleConnection = {
763
+ ...connection,
764
+ id: getEdgeId(connection)
765
+ };
766
+ const edge = store.onBeforeConnect?.(handleConnection) ?? handleConnection;
767
+ actions.addEdge(edge);
768
+ store.onConnect?.(handleConnection);
769
+ };
770
+ const onPointerDown = (event) => {
771
+ XYHandle2.onPointerDown(event, {
772
+ handleId: handleId(),
773
+ nodeId: nodeId(),
774
+ isTarget: isTarget(),
775
+ connectionRadius: store.connectionRadius,
776
+ domNode: store.domNode,
777
+ nodeLookup,
778
+ connectionMode: store.connectionMode,
779
+ lib: store.lib,
780
+ autoPanOnConnect: store.autoPanOnConnect,
781
+ flowId: store.id,
782
+ isValidConnection: local.isValidConnection ?? store.isValidConnection,
783
+ updateConnection: actions.setConnection,
784
+ cancelConnection: actions.cancelConnection,
785
+ panBy: actions.panBy,
786
+ onConnect: onConnectExtended,
787
+ onConnectStart: (event2, startParams) => {
788
+ store.onConnectStart?.(event2, {
789
+ nodeId: startParams.nodeId,
790
+ handleId: startParams.handleId,
791
+ handleType: startParams.handleType
792
+ });
793
+ },
794
+ onConnectEnd: store.onConnectEnd,
795
+ getTransform: () => store.transform,
796
+ getFromHandle: () => store.connection.fromHandle,
797
+ autoPanSpeed: store.autoPanSpeed,
798
+ dragThreshold: store.connectionDragThreshold,
799
+ handleDomNode: event.currentTarget
800
+ });
801
+ };
802
+ const onClick = (event) => {
803
+ if (!nodeId() || !store.clickConnectStartHandle && !local.isConnectableStart) {
804
+ return;
805
+ }
806
+ if (!store.clickConnectStartHandle) {
807
+ store.onClickConnectStart?.(event, {
808
+ nodeId: nodeId(),
809
+ handleId: handleId(),
810
+ handleType: local.type
811
+ });
812
+ actions.setClickConnectStartHandle({ nodeId: nodeId(), type: local.type, id: handleId() });
813
+ return;
814
+ }
815
+ const doc = getHostForElement(event.target);
816
+ const isValidConnectionHandler = local.isValidConnection ?? store.isValidConnection;
817
+ const { connection, isValid } = XYHandle2.isValid(event, {
818
+ handle: {
819
+ nodeId: nodeId(),
820
+ id: handleId(),
821
+ type: local.type
822
+ },
823
+ connectionMode: store.connectionMode,
824
+ fromNodeId: store.clickConnectStartHandle.nodeId,
825
+ fromHandleId: store.clickConnectStartHandle.id ?? null,
826
+ fromType: store.clickConnectStartHandle.type,
827
+ isValidConnection: isValidConnectionHandler,
828
+ flowId: store.id,
829
+ doc,
830
+ lib: store.lib,
831
+ nodeLookup
832
+ });
833
+ if (isValid && connection) {
834
+ onConnectExtended(connection);
835
+ }
836
+ const connectionClone = structuredClone(unwrap(store.connection));
837
+ delete connectionClone.inProgress;
838
+ connectionClone.toPosition = connectionClone.toHandle ? connectionClone.toHandle.position : null;
839
+ store.onClickConnectEnd?.(event, connectionClone);
840
+ actions.setClickConnectStartHandle(void 0);
841
+ };
842
+ const connectionIndicator = () => connectable() && (!connectionInProcess() || isPossibleTargetHandle()) && (connectionInProcess() || store.clickConnectStartHandle ? local.isConnectableEnd : local.isConnectableStart);
843
+ return <div
844
+ role="button"
845
+ aria-label={store.ariaLabelConfig[`handle.ariaLabel`]}
846
+ tabIndex={-1}
847
+ data-handleid={handleId()}
848
+ data-nodeid={nodeId()}
849
+ data-handlepos={local.position}
850
+ data-id={`${store.id}-${nodeId()}-${local.id || null}-${local.type}`}
851
+ onClick={store.clickConnect ? onClick : void 0}
852
+ onPointerDown={onPointerDown}
853
+ style={local.style}
854
+ class={clsx5(
855
+ "solid-flow__handle",
856
+ `solid-flow__handle-${local.position}`,
857
+ store.noDragClass,
858
+ store.noPanClass,
859
+ local.class,
860
+ {
861
+ valid: valid(),
862
+ connectingto: connectingTo(),
863
+ connectingfrom: connectingFrom(),
864
+ source: !isTarget(),
865
+ target: isTarget(),
866
+ connectablestart: _props.isConnectableStart,
867
+ connectableend: _props.isConnectableEnd,
868
+ connectable: connectable(),
869
+ connectionindicator: connectionIndicator()
870
+ }
871
+ )}
872
+ {...rest}
873
+ >
874
+ {local.children}
875
+ </div>;
876
+ };
877
+
878
+ // src/components/graph/node/DefaultNode.tsx
879
+ var DefaultNode = (props) => {
880
+ const _props = mergeProps5(
881
+ {
882
+ targetPosition: "top",
883
+ sourcePosition: "bottom"
884
+ },
885
+ props
886
+ );
887
+ return <>
888
+ <Handle type="target" position={_props.targetPosition} isConnectable={_props.isConnectable} />
889
+ {props.data.label}
890
+ <Handle type="source" position={_props.sourcePosition} isConnectable={_props.isConnectable} />
891
+ </>;
892
+ };
893
+
894
+ // src/components/graph/node/GroupNode.tsx
895
+ var GroupNode = (props) => <div
896
+ style={{
897
+ position: "absolute",
898
+ left: 0,
899
+ top: 0,
900
+ width: toPxString(props.width),
901
+ height: toPxString(props.height)
902
+ }}
903
+ />;
904
+
905
+ // src/components/graph/node/InputNode.tsx
906
+ import { mergeProps as mergeProps6 } from "solid-js";
907
+ var InputNode = (props) => {
908
+ const _props = mergeProps6(
909
+ {
910
+ sourcePosition: "bottom"
911
+ },
912
+ props
913
+ );
914
+ return <>
915
+ {props.data?.label}
916
+ <Handle type="source" position={_props.sourcePosition} isConnectable={_props.isConnectable} />
917
+ </>;
918
+ };
919
+
920
+ // src/components/graph/node/NodeWrapper.tsx
921
+ import {
922
+ elementSelectionKeys as elementSelectionKeys2,
923
+ getNodesInside as getNodesInside2,
924
+ isInputDOMNode,
925
+ nodeHasDimensions
926
+ } from "@xyflow/system";
927
+ import clsx6 from "clsx";
928
+ import { batch, createEffect as createEffect3, createSignal as createSignal4, Show as Show6 } from "solid-js";
929
+ import { Dynamic as Dynamic2 } from "solid-js/web";
930
+
931
+ // src/actions/createDraggable.tsx
932
+ import { XYDrag } from "@xyflow/system";
933
+ import { createEffect as createEffect2, createSignal as createSignal3, onCleanup, onMount } from "solid-js";
934
+ var createDraggable = (elem, params) => {
935
+ const { store, nodeLookup, actions } = useInternalSolidFlow();
936
+ const [dragging, setDragging] = createSignal3(false);
937
+ onMount(() => {
938
+ const { onDrag, onDragStart, onDragStop, onNodeMouseDown } = params();
939
+ const dragInstance = XYDrag({
940
+ onDrag,
941
+ onDragStart: (event, dragItems, node, nodes) => {
942
+ setDragging(true);
943
+ onDragStart?.(event, dragItems, node, nodes);
944
+ },
945
+ onDragStop: (event, dragItems, node, nodes) => {
946
+ setDragging(false);
947
+ onDragStop?.(event, dragItems, node, nodes);
948
+ },
949
+ onNodeMouseDown,
950
+ getStoreItems: () => {
951
+ return {
952
+ nodes: store.nodes,
953
+ nodeLookup,
954
+ edges: store.edges,
955
+ nodeExtent: store.nodeExtent,
956
+ snapGrid: store.snapGrid ?? [0, 0],
957
+ snapToGrid: !!store.snapGrid,
958
+ autoPanSpeed: store.autoPanSpeed,
959
+ nodeOrigin: store.nodeOrigin,
960
+ multiSelectionActive: store.multiselectionKeyPressed,
961
+ domNode: store.domNode,
962
+ transform: store.transform,
963
+ autoPanOnNodeDrag: store.autoPanOnNodeDrag,
964
+ nodesDraggable: store.nodesDraggable,
965
+ selectNodesOnDrag: store.selectNodesOnDrag,
966
+ nodeDragThreshold: store.nodeDragThreshold,
967
+ unselectNodesAndEdges: actions.unselectNodesAndEdges,
968
+ updateNodePositions: actions.updateNodePositions,
969
+ panBy: actions.panBy
970
+ };
971
+ }
972
+ });
973
+ function updateDrag(elem2, params2) {
974
+ if (params2.disabled) {
975
+ dragInstance.destroy();
976
+ return;
977
+ }
978
+ dragInstance.update({
979
+ domNode: elem2,
980
+ nodeId: params2.nodeId,
981
+ noDragClassName: params2.noDragClass,
982
+ handleSelector: params2.handleSelector,
983
+ isSelectable: params2.isSelectable,
984
+ nodeClickDistance: params2.nodeClickDistance
985
+ });
986
+ }
987
+ createEffect2(() => {
988
+ updateDrag(elem(), params());
989
+ });
990
+ onCleanup(() => {
991
+ dragInstance.destroy();
992
+ });
993
+ });
994
+ return dragging;
995
+ };
996
+ var createDraggable_default = createDraggable;
997
+
998
+ // src/components/contexts/nodeId.tsx
999
+ import { createContext as createContext3, useContext as useContext3 } from "solid-js";
1000
+ var NodeIdContext = createContext3();
1001
+ function useNodeId() {
1002
+ const ctx = useContext3(NodeIdContext);
1003
+ if (!ctx) {
1004
+ throw new Error(
1005
+ "solid-flow: Your application must be wrapped with <SolidFlow> in order to invoke useNodeId"
1006
+ );
1007
+ }
1008
+ return ctx;
1009
+ }
1010
+
1011
+ // src/components/graph/node/NodeWrapper.tsx
1012
+ var NodeWrapper = (props) => {
1013
+ const { store, nodeLookup, parentLookup, actions } = useInternalSolidFlow();
1014
+ const [nodeRef, setNodeRef] = createSignal4();
1015
+ const node = () => nodeLookup.get(props.nodeId);
1016
+ const nodeId = () => node().id;
1017
+ const nodeType = () => node().type ?? "default";
1018
+ const deletable = () => node().deletable ?? true;
1019
+ const selectable = () => node().selectable ?? store.elementsSelectable;
1020
+ const focusable = () => node().focusable ?? store.nodesFocusable;
1021
+ const draggable = () => node().draggable ?? store.nodesDraggable;
1022
+ const connectable = () => node().connectable ?? store.nodesConnectable;
1023
+ const userNode = () => node().internals.userNode;
1024
+ const nodeTypeValid = () => nodeType() in store.nodeTypes;
1025
+ const nodeComponent = () => store.nodeTypes[nodeType()];
1026
+ const isParentNode = () => parentLookup.has(node().id);
1027
+ const transform = () => {
1028
+ const { x, y } = node().internals.positionAbsolute;
1029
+ return `translate(${x}px, ${y}px)`;
1030
+ };
1031
+ const sizeStyle = () => {
1032
+ const w = node().width ?? node().initialWidth;
1033
+ const h = node().height ?? node().initialHeight;
1034
+ return {
1035
+ ...node().style,
1036
+ ...w ? { width: toPxString(w) } : {},
1037
+ ...h ? { height: toPxString(h) } : {}
1038
+ };
1039
+ };
1040
+ const style = () => ({
1041
+ "z-index": node().internals.z,
1042
+ transform: transform(),
1043
+ visibility: nodeHasDimensions(node()) ? "visible" : "hidden",
1044
+ ...sizeStyle(),
1045
+ ...node().style ?? {}
1046
+ });
1047
+ createEffect3(() => {
1048
+ if (!nodeTypeValid()) {
1049
+ }
1050
+ });
1051
+ createEffect3((prev) => {
1052
+ if (prev && prev.sourcePosition === node().sourcePosition && prev.targetPosition === node().targetPosition && prev.nodeType === nodeType()) {
1053
+ return prev;
1054
+ }
1055
+ actions.requestUpdateNodeInternals([
1056
+ [
1057
+ node().id,
1058
+ {
1059
+ id: node().id,
1060
+ nodeElement: nodeRef(),
1061
+ force: true
1062
+ }
1063
+ ]
1064
+ ]);
1065
+ return {
1066
+ nodeType: nodeType(),
1067
+ sourcePosition: node().sourcePosition,
1068
+ targetPosition: node().targetPosition
1069
+ };
1070
+ });
1071
+ createEffect3((prevNodeRef) => {
1072
+ const currentNodeRef = nodeRef();
1073
+ if (currentNodeRef === prevNodeRef && nodeHasDimensions(node())) {
1074
+ return prevNodeRef;
1075
+ }
1076
+ if (prevNodeRef) {
1077
+ props.resizeObserver.unobserve(prevNodeRef);
1078
+ }
1079
+ if (currentNodeRef) {
1080
+ props.resizeObserver.observe(currentNodeRef);
1081
+ }
1082
+ return currentNodeRef;
1083
+ });
1084
+ const onSelectNodeHandler = (event) => {
1085
+ if (selectable() && (!store.selectNodesOnDrag || !draggable() || store.nodeDragThreshold > 0)) {
1086
+ actions.handleNodeSelection(node().id);
1087
+ }
1088
+ props.onNodeClick?.({ node: userNode(), event });
1089
+ };
1090
+ const onKeyDown = (event) => {
1091
+ if (isInputDOMNode(event) || store.disableKeyboardA11y) {
1092
+ return;
1093
+ }
1094
+ if (elementSelectionKeys2.includes(event.key) && selectable()) {
1095
+ actions.handleNodeSelection(node().id, event.key === "Escape", nodeRef());
1096
+ return;
1097
+ }
1098
+ const arrowKeyDiff = ARROW_KEY_DIFFS[event.key];
1099
+ if (draggable() && node().selected && arrowKeyDiff) {
1100
+ batch(() => {
1101
+ event.preventDefault();
1102
+ actions.setAriaLiveMessage(
1103
+ store.ariaLabelConfig["node.a11yDescription.ariaLiveMessage"]({
1104
+ direction: event.key.replace("Arrow", "").toLowerCase(),
1105
+ x: ~~node().internals.positionAbsolute.x,
1106
+ y: ~~node().internals.positionAbsolute.y
1107
+ })
1108
+ );
1109
+ actions.moveSelectedNodes(arrowKeyDiff, event.shiftKey ? 4 : 1);
1110
+ });
1111
+ }
1112
+ };
1113
+ const onFocus = () => {
1114
+ if (store.disableKeyboardA11y || !store.autoPanOnNodeFocus || !nodeRef()?.matches(":focus-visible")) {
1115
+ return;
1116
+ }
1117
+ const { width, height, viewport } = store;
1118
+ const withinViewport = getNodesInside2(
1119
+ /* @__PURE__ */ new Map([[node().id, node()]]),
1120
+ { x: 0, y: 0, width, height },
1121
+ [viewport.x, viewport.y, viewport.zoom],
1122
+ true
1123
+ ).length > 0;
1124
+ if (withinViewport) return;
1125
+ void actions.setCenter(
1126
+ node().position.x + (node().measured.width ?? 0) / 2,
1127
+ node().position.y + (node().measured.height ?? 0) / 2,
1128
+ { zoom: viewport.zoom }
1129
+ );
1130
+ };
1131
+ const dragging = createDraggable_default(nodeRef, () => ({
1132
+ nodeId: node().id,
1133
+ isSelectable: selectable(),
1134
+ disabled: !draggable(),
1135
+ handleSelector: node().dragHandle,
1136
+ noDragClass: store.noDragClass,
1137
+ nodeClickDistance: props.nodeClickDistance,
1138
+ onNodeMouseDown: actions.handleNodeSelection,
1139
+ onDrag: (event, _, targetNode, nodes) => {
1140
+ props.onNodeDrag?.({ event, targetNode, nodes });
1141
+ },
1142
+ onDragStart: (event, _, targetNode, nodes) => {
1143
+ props.onNodeDragStart?.({
1144
+ event,
1145
+ targetNode,
1146
+ nodes
1147
+ });
1148
+ },
1149
+ onDragStop: (event, _, targetNode, nodes) => {
1150
+ props.onNodeDragStop?.({
1151
+ event,
1152
+ targetNode,
1153
+ nodes
1154
+ });
1155
+ }
1156
+ }));
1157
+ return <Show6 when={!node().hidden}>
1158
+ <div
1159
+ ref={setNodeRef}
1160
+ data-id={node().id}
1161
+ class={clsx6(
1162
+ "solid-flow__node",
1163
+ `solid-flow__node-${nodeType()}`,
1164
+ {
1165
+ connectable: connectable(),
1166
+ draggable: draggable(),
1167
+ dragging: dragging(),
1168
+ nopan: draggable(),
1169
+ parent: isParentNode(),
1170
+ selectable: selectable(),
1171
+ selected: node().selected
1172
+ },
1173
+ node().class
1174
+ )}
1175
+ style={style()}
1176
+ onClick={onSelectNodeHandler}
1177
+ onPointerEnter={(event) => props.onNodePointerEnter?.({ node: userNode(), event })}
1178
+ onPointerLeave={(event) => props.onNodePointerLeave?.({ node: userNode(), event })}
1179
+ onPointerMove={(event) => props.onNodePointerMove?.({ node: userNode(), event })}
1180
+ onContextMenu={(event) => props.onNodeContextMenu?.({ node: userNode(), event })}
1181
+ onKeyDown={(e) => focusable() && onKeyDown(e)}
1182
+ onFocus={() => focusable() && onFocus()}
1183
+ tabIndex={focusable() ? 0 : void 0}
1184
+ role={node().ariaRole ?? (focusable() ? "group" : void 0)}
1185
+ aria-roledescription="node"
1186
+ aria-describedby={store.disableKeyboardA11y ? void 0 : `${ARIA_NODE_DESC_KEY}-${store.id}`}
1187
+ {...node().domAttributes}
1188
+ >
1189
+ <NodeIdContext.Provider value={nodeId}>
1190
+ <NodeConnectableContext.Provider value={connectable}>
1191
+ <Dynamic2
1192
+ component={nodeComponent()}
1193
+ data={node().data}
1194
+ id={node().id}
1195
+ selected={Boolean(node().selected)}
1196
+ selectable={selectable()}
1197
+ deletable={deletable()}
1198
+ sourcePosition={node().sourcePosition}
1199
+ targetPosition={node().targetPosition}
1200
+ zIndex={node().internals.z}
1201
+ dragging={dragging()}
1202
+ draggable={draggable()}
1203
+ dragHandle={node().dragHandle}
1204
+ parentId={node().parentId}
1205
+ type={nodeType()}
1206
+ isConnectable={connectable()}
1207
+ positionAbsoluteX={node().internals.positionAbsolute.x}
1208
+ positionAbsoluteY={node().internals.positionAbsolute.y}
1209
+ width={node().width}
1210
+ height={node().height}
1211
+ />
1212
+ </NodeConnectableContext.Provider>
1213
+ </NodeIdContext.Provider>
58
1214
  </div>
59
- </Mi>};import{mergeProps as ki}from"solid-js";var Bo=e=>{let o=ki({targetPosition:"top"},e);return<>
60
- <Se type="target"position={o.targetPosition}isConnectable={o.isConnectable}/>
61
- {e.data?.label}
62
- </>};import{devWarn as Di,infiniteExtent as Oi}from"@xyflow/system";var we=()=>({id:"1",nodes:[],edges:[],nodeOrigin:[0,0],nodeExtent:Oi,defaultEdgeOptions:{},colorMode:"system",colorModeSSR:"light",connectionMode:"strict",connectionLineType:"default",connectionRadius:20,nodeDragThreshold:1,minZoom:.5,maxZoom:2,selectionMode:"partial",fitView:!1,noPanClass:"nopan",noDragClass:"nodrag",noWheelClass:"nowheel",autoPanOnNodeDrag:!0,autoPanOnConnect:!0,autoPanOnNodeFocus:!0,autoPanSpeed:15,elevateEdgesOnSelect:!0,nodesDraggable:!0,nodesConnectable:!0,nodesFocusable:!0,edgesFocusable:!0,elementsSelectable:!0,selectNodesOnDrag:!0,elevateNodesOnSelect:!0,onlyRenderVisibleElements:!1,disableKeyboardA11y:!1,defaultMarkerColor:"#b1b1b7",ariaLiveMessage:"",style:{},isValidConnection:()=>!0,onFlowError:Di});import{clampPosition as Vo,clampPositionToParent as zi,getBoundsOfRects as rg,getDimensions as ig,getHandleBounds as sg,getNodeDimensions as tn,getNodePositionWithOrigin as nn,infiniteExtent as Ri,isCoordinateExtent as rn,isNumeric as Ai,nodeToRect as dg}from"@xyflow/system";var sn={nodeOrigin:[0,0],nodeExtent:Ri,elevateNodesOnSelect:!0,defaults:{}},_i={...sn,checkEquality:!0};function dn(e,o){let t={...e};for(let N in o)o[N]!==void 0&&(t[N]=o[N]);return t}function an(e,o,t,N){let S=dn(_i,N),P=e.length>0,x=new Map(o),b=S?.elevateNodesOnSelect?1e3:0;o.clear(),t.clear();for(let C of e){let T=x.get(C.id);if(S.checkEquality&&C===T?.internals.userNode)o.set(C.id,T);else{let v=nn(C,S.nodeOrigin),E=rn(C.extent)?C.extent:S.nodeExtent,w=Vo(v,E,tn(C));T={...S.defaults,...C,measured:{width:C.measured?.width,height:C.measured?.height},internals:{positionAbsolute:w,handleBounds:C.measured?T?.internals.handleBounds:void 0,z:$e(C,b),userNode:C}},o.set(C.id,T)}(T.measured===void 0||T.measured.width===void 0||T.measured.height===void 0)&&!T.hidden&&(P=!1),C.parentId&&Ko(T,o,t,N)}return P}function Li(e,o){if(!e.parentId)return;let t=o.get(e.parentId);t?t.set(e.id,e):o.set(e.parentId,new Map([[e.id,e]]))}function Ko(e,o,t,N){let{elevateNodesOnSelect:S,nodeOrigin:P,nodeExtent:x}=dn(sn,N),b=e.parentId,C=o.get(b);if(!C)return;Li(e,t);let T=S?1e3:0,{x:v,y:E,z:w}=Hi(e,C,P,x,T),{positionAbsolute:I}=e.internals,D=v!==I.x||E!==I.y;(D||w!==e.internals.z)&&o.set(e.id,{...e,internals:{...e.internals,positionAbsolute:D?{x:v,y:E}:I,z:w}})}function $e(e,o){return(Ai(e.zIndex)?e.zIndex:0)+(e.selected?o:0)}function Hi(e,o,t,N,S){let{x:P,y:x}=o.internals.positionAbsolute,b=tn(e),C=nn(e,t),T=rn(e.extent)?Vo(C,e.extent,b):C,v=Vo({x:P+T.x,y:x+T.y},N,b);e.extent==="parent"&&(v=zi(v,b,o));let E=$e(e,S),w=o.internals.z??0;return{x:v.x,y:v.y,z:w>=E?w+1:E}}function Xo(e,o,t,N,S,P){let x=S,b=N.get(x)||new Map;N.set(x,b.set(t,o)),x=`${S}-${e}`;let C=N.get(x)||new Map;if(N.set(x,C.set(t,o)),P){x=`${S}-${e}-${P}`;let T=N.get(x)||new Map;N.set(x,T.set(t,o))}}function Fo(e,o,t,N,S){let P=N,x=t.get(P);x&&(x.delete(o),x.size===0&&t.delete(P)),P=`${N}-${e}`;let b=t.get(P);if(b&&(b.delete(o),b.size===0&&t.delete(P)),S){P=`${N}-${e}-${S}`;let C=t.get(P);C&&(C.delete(o),C.size===0&&t.delete(P))}}var is={input:_o,output:Bo,default:Ro,group:Ao},ss={straight:Oo,smoothstep:ko,default:To,step:Do},ds=(e,o,t,N,S,P)=>{if(o&&!t&&N&&S){let x=Zi(P,{filter:b=>!!((b.width||b.initialWidth)&&(b.height||b.initialHeight))});return Ji(x,N,S,.5,2,.1)}else return t??{x:0,y:0,zoom:1}},Je=e=>{let o=pn(we(),e),t=new ze,N=new ze,S=new ze,P=new ze,x=new ze,b=Ce(()=>an(o.nodes,t,N,{nodeExtent:o.nodeExtent,nodeOrigin:o.nodeOrigin,elevateNodesOnSelect:o.elevateNodesOnSelect,checkEquality:!0})),C=ds(b,o.fitView,o.initialViewport,o.width??0,o.height??0,t),T=Bi("(prefers-color-scheme: dark)",o.colorModeSSR==="dark"),[v,E]=re(o),[w,I]=se(()=>Qi(v().ariaLabelConfig)),[D,k]=se(()=>v().ariaLiveMessage),[R,Y]=re(void 0),[H,_]=re(Yo),[$,ee]=re(null),[ie,de]=re(!1),[U,G]=se(()=>v().elementsSelectable),[O,F]=se(()=>v().height),[K,Z]=se(()=>v().minZoom),[te,Ot]=se(()=>v().maxZoom),[Le,An]=se(()=>v().nodesDraggable),[_n,Ln]=se(()=>v().nodesDraggable),[bo,Hn]=re(null),[Bn,He]=re(),[Vn,Be]=re(),[Kn,Xn]=se(()=>v().snapGrid),[Fn,Cl]=se(()=>v().translateExtent??Gi),[Yn,Wn]=se(()=>v().width),[Zn,zt]=re(!1),[$n,Rt]=re(!1),[Un,At]=re(!1),[Jn,_t]=re(!1),[Gn,Lt]=re(!1),be=Fe(()=>v().nodes),Ve=Fe(()=>v().edges),Ee=Fe(()=>v().viewport??C),jn=Ue(()=>[Ee.get().x,Ee.get().y,Ee.get().zoom]),A=pn({width:0,height:0},v,{get _colorMode(){return v().colorMode},get _colorModeSSR(){return v().colorModeSSR},get _connection(){return H()},get _nodeTypes(){return v().nodeTypes},get _edgeTypes(){return v().edgeTypes},get ariaLabelConfig(){return w()},get ariaLiveMessage(){return D()},get clickConnectStartHandle(){return R()},get colorMode(){return this._colorMode==="system"?T()?"dark":"light":this._colorMode},get connection(){let M=H();return{...M,from:M.inProgress?ln(M.from,this.transform):M.from,to:M.inProgress?ln(M.to,this.transform):M.to}},get domNode(){return $()},get dragging(){return ie()},get edgeTypes(){return{...ss,...this._edgeTypes}},get elementsSelectable(){return U()},get height(){return O()},get lib(){return"solid"},get onError(){return v().onFlowError},get maxZoom(){return te()},get minZoom(){return K()},get nodes(){return be.get()},get nodesConnectable(){return Le()},get nodesDraggable(){return _n()},get nodeTypes(){return{...is,...this._nodeTypes}},get panZoom(){return bo()},get selectedNodes(){return v().nodes.filter(M=>M.selected)},get selectedEdges(){return v().edges.filter(M=>M.selected)},get selectionRect(){return Bn()},get selectionRectMode(){return Vn()},get snapGrid(){return Kn()},get viewport(){return Ee.get()},get viewportInitialized(){return bo()!==null},get visibleEdgeIds(){return Qn()},get visibleNodeIds(){return qn()},get visibleNodesMap(){return Ht()},get transform(){return jn()},get translateExtent(){return Fn()},get width(){return Yn()},get selectionKeyPressed(){return Zn()},get multiselectionKeyPressed(){return $n()},get deleteKeyPressed(){return Un()},get panActivationKeyPressed(){return Jn()},get zoomActivationKeyPressed(){return Gn()}}),Ht=Ue(()=>t),qn=Ue(()=>Array.from(Ht().values()).map(M=>M.id)),Qn=Ue(()=>Array.from(x.values()).map(M=>M.id)),er=M=>x.get(M),Bt=async M=>A.panZoom?Fi({nodes:t,width:A.width,height:A.height,panZoom:A.panZoom,minZoom:A.minZoom,maxZoom:A.maxZoom},M??v().fitViewOptions):!1,Vt=()=>{de(!1),He(void 0),Be(void 0),zt(!1),Rt(!1),At(!1),_t(!1),Lt(!1),_({...Yo}),Y(void 0),Ee.set(v().initialViewport??{x:0,y:0,zoom:1}),k(""),Xn(void 0)},or=M=>{Ve.set(L=>Vi(M,L))},Eo=!1,tr=M=>{Eo=!M},Kt=(M,L=!1)=>{be.set(X=>M.has(X.id),ve(X=>{X.dragging=L,X.position=M.get(X.id).position}))},Ie,nr=M=>{if(Ie){Ie.push(...M);return}Ie=M,requestIdleCallback(()=>{Ce(()=>{let L=new Map(Ie);Ie=void 0;let{changes:X,updatedInternals:B}=ns(L,t,N,A.domNode,A.nodeOrigin);if(!B)return;ts(t,N,{nodeOrigin:A.nodeOrigin,nodeExtent:A.nodeExtent});let V=X.reduce((W,ne)=>{let oe=t.get(ne.id)?.internals.userNode;return oe&&W.set(oe.id,ne),W},new Map);be.set(W=>V.has(W.id),ve(W=>{let ne=V.get(W.id);switch(ne.type){case"dimensions":{ne.setAttributes&&(W.width=ne.dimensions?.width??W.width,W.height=ne.dimensions?.height??W.height),W.measured={...W.measured,...ne.dimensions};break}case"position":W.position=ne.position??W.position;break}})),Eo||(Eo=!0,Bt())})})},Xt=async(M,L)=>A.panZoom?A.panZoom.scaleBy(M,L):!1,rr=M=>Xt(1.2,M),ir=M=>Xt(1/1.2,M),sr=async(M,L,X)=>{let B=typeof X?.zoom<"u"?X.zoom:A.maxZoom,V=A.panZoom;return V?(await V.setViewport({x:A.width/2-M*B,y:A.height/2-L*B,zoom:B},{duration:X?.duration,ease:X?.ease,interpolate:X?.interpolate}),Promise.resolve(!0)):Promise.resolve(!1)},dr=M=>{A.panZoom?.setClickDistance(M)},xe=({nodes:M,edges:L}={})=>{let X=new Set((M||A.nodes).map(({id:V})=>V));X.size&&be.set(V=>X.has(V.id),ve(V=>{V.selected=!1}));let B=new Set((L||A.edges).map(({id:V})=>V));B.size&&Ve.set(V=>B.has(V.id),ve(V=>{V.selected=!1}))},Ft=M=>{let L=A.multiselectionKeyPressed,X=new Map;be.set(B=>{let V=M.includes(B.id),W=L&&B.selected||V;return X.set(B.id,W),B.selected!==W},ve(B=>{let V=t.get(B.id);V&&(V.selected=X.get(B.id)),B.selected=X.get(B.id)})),L||xe({nodes:[]})},Yt=M=>{let L=A.multiselectionKeyPressed,X=new Map;Ve.set(B=>{let V=M.includes(B.id),W=L&&B.selected||V;return X.set(B.id,W),B.selected!==W},ve(B=>{B.selected=X.get(B.id)})),L||xe({edges:[]})},ar=(M,L,X)=>{let B=A.nodes.find(V=>V.id===M);B&&(Ce(()=>{He(void 0),Be(void 0)}),B.selected?(L||B.selected&&A.multiselectionKeyPressed)&&(xe({nodes:[B],edges:[]}),requestAnimationFrame(()=>X?.blur())):Ft([M]))},lr=M=>{let L=S.get(M);!L||!(L.selectable||A.elementsSelectable&&typeof L.selectable>"u")||(Ce(()=>{He(void 0),Be(void 0)}),L.selected?L.selected&&A.multiselectionKeyPressed&&xe({nodes:[],edges:[L]}):Yt([M]))},cr=(M,L)=>{let X=new Map,B=A.snapGrid?.[0]??5,V=A.snapGrid?.[1]??5,W=M.x*B*L,ne=M.y*V*L;for(let oe of t.values()){if(!(oe.selected&&(oe.draggable||A.nodesDraggable&&typeof oe.draggable>"u")))continue;let ae={x:oe.internals.positionAbsolute.x+W,y:oe.internals.positionAbsolute.y+ne};A.snapGrid&&(ae=os(ae,A.snapGrid));let{position:Ke,positionAbsolute:Wt}=Ki({nodeId:oe.id,nextPosition:ae,nodeLookup:t,nodeExtent:A.nodeExtent,nodeOrigin:A.nodeOrigin,onError:A.onError});oe.position=Ke,oe.internals.positionAbsolute=Wt,X.set(oe.id,oe)}Kt(X)},pr=M=>es({delta:M,panZoom:A.panZoom,transform:A.transform,translateExtent:A.translateExtent,width:A.width,height:A.height}),gr=()=>{_({...Yo})},mr=()=>{Vt(),xe()};return Te(()=>{A.panZoom?.syncViewport(A.viewport)}),Te(()=>{let M=bo();M&&(Te(()=>{M.setScaleExtent([A.minZoom,A.maxZoom])}),Te(()=>{M.setTranslateExtent(A.translateExtent)}))}),Re(cn(()=>A.nodes,M=>{Re(()=>{let L=rs(()=>t.get(M.id)),X=A.elevateNodesOnSelect?1e3:0,B=Xi(Ui(M,A.nodeOrigin),ji(M.extent)?M.extent:A.nodeExtent,$i(M)),V={width:M.measured?.width??L?.measured?.width,height:M.measured?.height??L?.measured?.height},W={...M,measured:V,internals:{positionAbsolute:B,handleBounds:!M.measured&&!L?.measured?void 0:L?.internals.handleBounds,z:$e(M,X),userNode:M}};t.set(M.id,W),M.parentId&&Ko(W,t,N,{nodeOrigin:A.nodeOrigin,nodeExtent:A.nodeExtent,elevateNodesOnSelect:A.elevateNodesOnSelect,checkEquality:!0})}),gn(()=>{})})),Te(()=>{let M=new Set(A.nodes.map(L=>L.id));for(let L of Array.from(t.keys()))M.has(L)||t.delete(L)}),Re(cn(()=>A.edges,M=>{let{source:L,target:X,sourceHandle:B=null,targetHandle:V=null}=M,W={edgeId:M.id,source:L,target:X,sourceHandle:B,targetHandle:V},ne=`${L}-${B}--${X}-${V}`,oe=`${X}-${V}--${L}-${B}`;Re(()=>{Ce(()=>{Xo("source",W,oe,P,L,B),Xo("target",W,ne,P,X,V),S.set(M.id,M)})}),Re(()=>{let ce=t.get(M.source),ae=t.get(M.target);if(!ce||!ae)return;if(A.onlyRenderVisibleElements){if(!qi({sourceNode:ce,targetNode:ae,width:A.width??0,height:A.height??0,transform:A.transform}))return;A.visibleNodesMap.set(ce.id,ce),A.visibleNodesMap.set(ae.id,ae)}let Ke=Yi({id:M.id,sourceNode:ce,targetNode:ae,sourceHandle:M.sourceHandle||null,targetHandle:M.targetHandle||null,connectionMode:A.connectionMode,onError:A.onError});Ke&&x.set(M.id,{...A.defaultEdgeOptions,...M,...Ke,zIndex:Wi({selected:M.selected,zIndex:M.zIndex??A.defaultEdgeOptions.zIndex,sourceNode:ce,targetNode:ae,elevateOnSelect:A.elevateEdgesOnSelect}),sourceNode:ce,targetNode:ae,edge:M})}),gn(()=>{Ce(()=>{S.delete(M.id),x.delete(M.id),Fo("source",oe,P,L,B),Fo("target",ne,P,X,V)})})})),Te(()=>{let M=new Set(A.edges.map(L=>L.id));for(let L of Array.from(S.keys()))M.has(L)||(S.delete(L),P.delete(L),x.delete(L))}),{store:A,nodeLookup:t,edgeLookup:S,parentLookup:N,connectionLookup:P,actions:{getEdge:er,applyInitialFitView:tr,resetStoreValues:Vt,requestUpdateNodeInternals:nr,setAriaLabelConfig:I,setAriaLiveMessage:k,setClickConnectStartHandle:Y,setConfig:E,setConnection:_,setDeleteKeyPressed:At,setDomNode:ee,setDragging:de,get setEdges(){return Ve.set},setElementsSelectable:G,setHeight:F,setMultiselectionKeyPressed:Rt,get setNodes(){return be.set},setNodesConnectable:An,setNodesDraggable:Ln,setPanActivationKeyPressed:_t,setPanZoom:Hn,setSelectionKeyPressed:zt,setSelectionRect:He,setSelectionRectMode:Be,get setViewport(){return Ee.set},setWidth:Wn,setZoomActivationKeyPressed:Lt,addEdge:or,updateNodePositions:Kt,zoomIn:rr,zoomOut:ir,fitView:Bt,setCenter:sr,setPaneClickDistance:dr,unselectNodesAndEdges:xe,addSelectedNodes:Ft,addSelectedEdges:Yt,handleNodeSelection:ar,handleEdgeSelection:lr,moveSelectedNodes:cr,panBy:pr,cancelConnection:gr,reset:mr}}};var Ae=as();function z(){let e=ls(Ae);if(!e)throw new Error("solid-flow: Your application must be wrapped with <SolidFlow> in order to invoke useInternalSolidFlow within your components");return e}import{mergeProps as cs,Show as Ss}from"solid-js";var Wo=e=>{let o=cs({markerUnits:"strokeWidth",orient:"auto-start-reverse",width:12.5,height:12.5,color:"none"},e),t=()=>o.color??"var(--xy-edge-stroke)";return<marker class="solid-flow__arrowhead"id={o.id}markerWidth={o.width}markerHeight={o.height}viewBox="-10 -10 20 20"markerUnits={o.markerUnits}orient={o.orient}refX="0"refY="0">
63
- <Ss when={o.type==="arrow"}fallback={<polyline class="arrowclosed"stroke={t()}fill={t()}stroke-linecap="round"stroke-linejoin="round"stroke-width={o.strokeWidth}points="-5,-4 0,0 -5,4 -5,-4"/>}>
64
- <polyline class="arrow"stroke={t()}fill="none"stroke-linecap="round"stroke-linejoin="round"stroke-width={o.strokeWidth}points="-5,-4 0,0 -5,4"/>
65
- </Ss>
66
- </marker>};import{createMarkerIds as Ns}from"@xyflow/system";import{createMemo as Ps,For as Es,Show as Cs}from"solid-js";var Zo=()=>{let{store:e}=z(),o=Ps(()=>Ns(e.edges,{id:e.id,defaultColor:e.defaultMarkerColor,defaultMarkerStart:e.defaultEdgeOptions.markerStart,defaultMarkerEnd:e.defaultEdgeOptions.markerEnd}));return<Cs when={o().length>0}>
1215
+ </Show6>;
1216
+ };
1217
+
1218
+ // src/components/graph/node/OutputNode.tsx
1219
+ import { mergeProps as mergeProps7 } from "solid-js";
1220
+ var OutputNode = (props) => {
1221
+ const _props = mergeProps7(
1222
+ {
1223
+ targetPosition: "top"
1224
+ },
1225
+ props
1226
+ );
1227
+ return <>
1228
+ <Handle type="target" position={_props.targetPosition} isConnectable={_props.isConnectable} />
1229
+ {props.data?.label}
1230
+ </>;
1231
+ };
1232
+
1233
+ // src/data/defaults.ts
1234
+ import {
1235
+ devWarn,
1236
+ infiniteExtent
1237
+ } from "@xyflow/system";
1238
+ var getDefaultFlowStateProps = () => ({
1239
+ id: "1",
1240
+ nodes: [],
1241
+ edges: [],
1242
+ nodeOrigin: [0, 0],
1243
+ nodeExtent: infiniteExtent,
1244
+ defaultEdgeOptions: {},
1245
+ colorMode: "system",
1246
+ colorModeSSR: "light",
1247
+ connectionMode: "strict",
1248
+ connectionLineType: "default",
1249
+ connectionRadius: 20,
1250
+ nodeDragThreshold: 1,
1251
+ minZoom: 0.5,
1252
+ maxZoom: 2,
1253
+ selectionMode: "partial",
1254
+ fitView: false,
1255
+ noPanClass: "nopan",
1256
+ noDragClass: "nodrag",
1257
+ noWheelClass: "nowheel",
1258
+ autoPanOnNodeDrag: true,
1259
+ autoPanOnConnect: true,
1260
+ autoPanOnNodeFocus: true,
1261
+ autoPanSpeed: 15,
1262
+ elevateEdgesOnSelect: true,
1263
+ nodesDraggable: true,
1264
+ nodesConnectable: true,
1265
+ nodesFocusable: true,
1266
+ edgesFocusable: true,
1267
+ elementsSelectable: true,
1268
+ selectNodesOnDrag: true,
1269
+ elevateNodesOnSelect: true,
1270
+ onlyRenderVisibleElements: false,
1271
+ disableKeyboardA11y: false,
1272
+ defaultMarkerColor: "#b1b1b7",
1273
+ ariaLiveMessage: "",
1274
+ style: {},
1275
+ isValidConnection: () => true,
1276
+ onFlowError: devWarn
1277
+ });
1278
+
1279
+ // src/data/xyflow.ts
1280
+ import {
1281
+ clampPosition,
1282
+ clampPositionToParent,
1283
+ getBoundsOfRects,
1284
+ getDimensions,
1285
+ getHandleBounds,
1286
+ getNodeDimensions,
1287
+ getNodePositionWithOrigin,
1288
+ infiniteExtent as infiniteExtent2,
1289
+ isCoordinateExtent,
1290
+ isNumeric,
1291
+ nodeToRect
1292
+ } from "@xyflow/system";
1293
+ var defaultOptions = {
1294
+ nodeOrigin: [0, 0],
1295
+ nodeExtent: infiniteExtent2,
1296
+ elevateNodesOnSelect: true,
1297
+ defaults: {}
1298
+ };
1299
+ var adoptUserNodesDefaultOptions = {
1300
+ ...defaultOptions,
1301
+ checkEquality: true
1302
+ };
1303
+ function mergeObjects(base, incoming) {
1304
+ const result = { ...base };
1305
+ for (const key in incoming) {
1306
+ if (incoming[key] !== void 0) {
1307
+ result[key] = incoming[key];
1308
+ }
1309
+ }
1310
+ return result;
1311
+ }
1312
+ function adoptUserNodes(nodes, nodeLookup, parentLookup, options) {
1313
+ const _options = mergeObjects(adoptUserNodesDefaultOptions, options);
1314
+ let nodesInitialized = nodes.length > 0;
1315
+ const tmpLookup = new Map(nodeLookup);
1316
+ const selectedNodeZ = _options?.elevateNodesOnSelect ? 1e3 : 0;
1317
+ nodeLookup.clear();
1318
+ parentLookup.clear();
1319
+ for (const userNode of nodes) {
1320
+ let internalNode = tmpLookup.get(userNode.id);
1321
+ if (_options.checkEquality && userNode === internalNode?.internals.userNode) {
1322
+ nodeLookup.set(userNode.id, internalNode);
1323
+ } else {
1324
+ const positionWithOrigin = getNodePositionWithOrigin(userNode, _options.nodeOrigin);
1325
+ const extent = isCoordinateExtent(userNode.extent) ? userNode.extent : _options.nodeExtent;
1326
+ const clampedPosition = clampPosition(
1327
+ positionWithOrigin,
1328
+ extent,
1329
+ getNodeDimensions(userNode)
1330
+ );
1331
+ internalNode = {
1332
+ ..._options.defaults,
1333
+ ...userNode,
1334
+ measured: {
1335
+ width: userNode.measured?.width,
1336
+ height: userNode.measured?.height
1337
+ },
1338
+ internals: {
1339
+ positionAbsolute: clampedPosition,
1340
+ // if user re-initializes the node or removes `measured` for whatever reason, we reset the handleBounds so that the node gets re-measured
1341
+ handleBounds: !userNode.measured ? void 0 : internalNode?.internals.handleBounds,
1342
+ z: calculateZ(userNode, selectedNodeZ),
1343
+ userNode
1344
+ }
1345
+ };
1346
+ nodeLookup.set(userNode.id, internalNode);
1347
+ }
1348
+ if ((internalNode.measured === void 0 || internalNode.measured.width === void 0 || internalNode.measured.height === void 0) && !internalNode.hidden) {
1349
+ nodesInitialized = false;
1350
+ }
1351
+ if (userNode.parentId) {
1352
+ updateChildNode(internalNode, nodeLookup, parentLookup, options);
1353
+ }
1354
+ }
1355
+ return nodesInitialized;
1356
+ }
1357
+ function updateParentLookup(node, parentLookup) {
1358
+ if (!node.parentId) {
1359
+ return;
1360
+ }
1361
+ const childNodes = parentLookup.get(node.parentId);
1362
+ if (childNodes) {
1363
+ childNodes.set(node.id, node);
1364
+ } else {
1365
+ parentLookup.set(node.parentId, /* @__PURE__ */ new Map([[node.id, node]]));
1366
+ }
1367
+ }
1368
+ function updateChildNode(node, nodeLookup, parentLookup, options) {
1369
+ const { elevateNodesOnSelect, nodeOrigin, nodeExtent } = mergeObjects(defaultOptions, options);
1370
+ const parentId = node.parentId;
1371
+ const parentNode = nodeLookup.get(parentId);
1372
+ if (!parentNode) {
1373
+ return;
1374
+ }
1375
+ updateParentLookup(node, parentLookup);
1376
+ const selectedNodeZ = elevateNodesOnSelect ? 1e3 : 0;
1377
+ const { x, y, z } = calculateChildXYZ(node, parentNode, nodeOrigin, nodeExtent, selectedNodeZ);
1378
+ const { positionAbsolute } = node.internals;
1379
+ const positionChanged = x !== positionAbsolute.x || y !== positionAbsolute.y;
1380
+ if (positionChanged || z !== node.internals.z) {
1381
+ nodeLookup.set(node.id, {
1382
+ ...node,
1383
+ internals: {
1384
+ ...node.internals,
1385
+ positionAbsolute: positionChanged ? { x, y } : positionAbsolute,
1386
+ z
1387
+ }
1388
+ });
1389
+ }
1390
+ }
1391
+ function calculateZ(node, selectedNodeZ) {
1392
+ return (isNumeric(node.zIndex) ? node.zIndex : 0) + (node.selected ? selectedNodeZ : 0);
1393
+ }
1394
+ function calculateChildXYZ(childNode, parentNode, nodeOrigin, nodeExtent, selectedNodeZ) {
1395
+ const { x: parentX, y: parentY } = parentNode.internals.positionAbsolute;
1396
+ const childDimensions = getNodeDimensions(childNode);
1397
+ const positionWithOrigin = getNodePositionWithOrigin(childNode, nodeOrigin);
1398
+ const clampedPosition = isCoordinateExtent(childNode.extent) ? clampPosition(positionWithOrigin, childNode.extent, childDimensions) : positionWithOrigin;
1399
+ let absolutePosition = clampPosition(
1400
+ { x: parentX + clampedPosition.x, y: parentY + clampedPosition.y },
1401
+ nodeExtent,
1402
+ childDimensions
1403
+ );
1404
+ if (childNode.extent === "parent") {
1405
+ absolutePosition = clampPositionToParent(absolutePosition, childDimensions, parentNode);
1406
+ }
1407
+ const childZ = calculateZ(childNode, selectedNodeZ);
1408
+ const parentZ = parentNode.internals.z ?? 0;
1409
+ return {
1410
+ x: absolutePosition.x,
1411
+ y: absolutePosition.y,
1412
+ z: parentZ >= childZ ? parentZ + 1 : childZ
1413
+ };
1414
+ }
1415
+ function addConnectionToLookup(type, connection, connectionKey, connectionLookup, nodeId, handleId) {
1416
+ let key = nodeId;
1417
+ const nodeMap = connectionLookup.get(key) || /* @__PURE__ */ new Map();
1418
+ connectionLookup.set(key, nodeMap.set(connectionKey, connection));
1419
+ key = `${nodeId}-${type}`;
1420
+ const typeMap = connectionLookup.get(key) || /* @__PURE__ */ new Map();
1421
+ connectionLookup.set(key, typeMap.set(connectionKey, connection));
1422
+ if (handleId) {
1423
+ key = `${nodeId}-${type}-${handleId}`;
1424
+ const handleMap = connectionLookup.get(key) || /* @__PURE__ */ new Map();
1425
+ connectionLookup.set(key, handleMap.set(connectionKey, connection));
1426
+ }
1427
+ }
1428
+ function removeConnectionFromLookup(type, connectionKey, connectionLookup, nodeId, handleId) {
1429
+ let key = nodeId;
1430
+ const nodeMap = connectionLookup.get(key);
1431
+ if (nodeMap) {
1432
+ nodeMap.delete(connectionKey);
1433
+ if (nodeMap.size === 0) connectionLookup.delete(key);
1434
+ }
1435
+ key = `${nodeId}-${type}`;
1436
+ const typeMap = connectionLookup.get(key);
1437
+ if (typeMap) {
1438
+ typeMap.delete(connectionKey);
1439
+ if (typeMap.size === 0) connectionLookup.delete(key);
1440
+ }
1441
+ if (handleId) {
1442
+ key = `${nodeId}-${type}-${handleId}`;
1443
+ const handleMap = connectionLookup.get(key);
1444
+ if (handleMap) {
1445
+ handleMap.delete(connectionKey);
1446
+ if (handleMap.size === 0) connectionLookup.delete(key);
1447
+ }
1448
+ }
1449
+ }
1450
+
1451
+ // src/data/createSolidFlow.tsx
1452
+ var InitialNodeTypesMap = {
1453
+ input: InputNode,
1454
+ output: OutputNode,
1455
+ default: DefaultNode,
1456
+ group: GroupNode
1457
+ };
1458
+ var InitialEdgeTypesMap = {
1459
+ straight: StraightEdgeInternal,
1460
+ smoothstep: SmoothStepEdgeInternal,
1461
+ default: BezierEdgeInternal,
1462
+ step: StepEdgeInternal
1463
+ };
1464
+ var getInitialViewport = (_nodesInitialized, fitView, initialViewport, width, height, nodeLookup) => {
1465
+ if (fitView && !initialViewport && width && height) {
1466
+ const bounds = getInternalNodesBounds(nodeLookup, {
1467
+ filter: (node) => !!((node.width || node.initialWidth) && (node.height || node.initialHeight))
1468
+ });
1469
+ return getViewportForBounds(bounds, width, height, 0.5, 2, 0.1);
1470
+ } else {
1471
+ return initialViewport ?? { x: 0, y: 0, zoom: 1 };
1472
+ }
1473
+ };
1474
+ var createSolidFlow = (props) => {
1475
+ const _props = mergeProps8(getDefaultFlowStateProps(), props);
1476
+ const nodeLookup = new ReactiveMap();
1477
+ const parentLookup = new ReactiveMap();
1478
+ const edgeLookup = new ReactiveMap();
1479
+ const connectionLookup = new ReactiveMap();
1480
+ const layoutedEdgesMap = new ReactiveMap();
1481
+ const startNodesInitialized = batch2(() => {
1482
+ return adoptUserNodes(_props.nodes, nodeLookup, parentLookup, {
1483
+ // eslint-disable-next-line solid/reactivity
1484
+ nodeExtent: _props.nodeExtent,
1485
+ // eslint-disable-next-line solid/reactivity
1486
+ nodeOrigin: _props.nodeOrigin,
1487
+ // eslint-disable-next-line solid/reactivity
1488
+ elevateNodesOnSelect: _props.elevateNodesOnSelect,
1489
+ checkEquality: true
1490
+ });
1491
+ });
1492
+ const initialViewport = getInitialViewport(
1493
+ startNodesInitialized,
1494
+ // eslint-disable-next-line solid/reactivity
1495
+ _props.fitView,
1496
+ _props.initialViewport,
1497
+ // eslint-disable-next-line solid/reactivity
1498
+ _props.width ?? 0,
1499
+ // eslint-disable-next-line solid/reactivity
1500
+ _props.height ?? 0,
1501
+ nodeLookup
1502
+ );
1503
+ const mediaPrefersDark = createMediaQuery(
1504
+ "(prefers-color-scheme: dark)",
1505
+ // NOTE: should mediaPrefersDark be reactive to config-changes?
1506
+ _props.colorModeSSR === "dark"
1507
+ );
1508
+ const [config, setConfig] = createSignal5(_props);
1509
+ const [ariaLabelConfig, setAriaLabelConfig] = createWritable(
1510
+ () => mergeAriaLabelConfig(config().ariaLabelConfig)
1511
+ );
1512
+ const [ariaLiveMessage, setAriaLiveMessage] = createWritable(() => config().ariaLiveMessage);
1513
+ const [clickConnectStartHandle, setClickConnectStartHandle] = createSignal5(void 0);
1514
+ const [connection, setConnection] = createSignal5(initialConnection);
1515
+ const [domNode, setDomNode] = createSignal5(null);
1516
+ const [dragging, setDragging] = createSignal5(false);
1517
+ const [elementsSelectable, setElementsSelectable] = createWritable(
1518
+ () => config().elementsSelectable
1519
+ );
1520
+ const [height, setHeight] = createWritable(() => config().height);
1521
+ const [minZoom, _setMinZoom] = createWritable(() => config().minZoom);
1522
+ const [maxZoom, _setMaxZoom] = createWritable(() => config().maxZoom);
1523
+ const [nodesConnectable, setNodesConnectable] = createWritable(() => config().nodesDraggable);
1524
+ const [nodesDraggable, setNodesDraggable] = createWritable(() => config().nodesDraggable);
1525
+ const [panZoom, setPanZoom] = createSignal5(null);
1526
+ const [selectionRect, setSelectionRect] = createSignal5();
1527
+ const [selectionRectMode, setSelectionRectMode] = createSignal5();
1528
+ const [snapGrid, setSnapGrid] = createWritable(() => config().snapGrid);
1529
+ const [translateExtent, _setTranslateExtent] = createWritable(
1530
+ () => config().translateExtent ?? infiniteExtent3
1531
+ );
1532
+ const [width, setWidth] = createWritable(() => config().width);
1533
+ const [selectionKeyPressed, setSelectionKeyPressed] = createSignal5(false);
1534
+ const [multiselectionKeyPressed, setMultiselectionKeyPressed] = createSignal5(false);
1535
+ const [deleteKeyPressed, setDeleteKeyPressed] = createSignal5(false);
1536
+ const [panActivationKeyPressed, setPanActivationKeyPressed] = createSignal5(false);
1537
+ const [zoomActivationKeyPressed, setZoomActivationKeyPressed] = createSignal5(false);
1538
+ const nodesMemo = createWritableStore(() => config().nodes);
1539
+ const edgesMemo = createWritableStore(() => config().edges);
1540
+ const viewportMemo = createWritableStore(() => config().viewport ?? initialViewport);
1541
+ const transform = createMemo5(
1542
+ () => [viewportMemo.get().x, viewportMemo.get().y, viewportMemo.get().zoom]
1543
+ );
1544
+ const store = mergeProps8({ width: 0, height: 0 }, config, {
1545
+ get _colorMode() {
1546
+ return config().colorMode;
1547
+ },
1548
+ get _colorModeSSR() {
1549
+ return config().colorModeSSR;
1550
+ },
1551
+ get _connection() {
1552
+ return connection();
1553
+ },
1554
+ get _nodeTypes() {
1555
+ return config().nodeTypes;
1556
+ },
1557
+ get _edgeTypes() {
1558
+ return config().edgeTypes;
1559
+ },
1560
+ get ariaLabelConfig() {
1561
+ return ariaLabelConfig();
1562
+ },
1563
+ get ariaLiveMessage() {
1564
+ return ariaLiveMessage();
1565
+ },
1566
+ get clickConnectStartHandle() {
1567
+ return clickConnectStartHandle();
1568
+ },
1569
+ get colorMode() {
1570
+ return this._colorMode === "system" ? mediaPrefersDark() ? "dark" : "light" : this._colorMode;
1571
+ },
1572
+ get connection() {
1573
+ const state = connection();
1574
+ return {
1575
+ ...state,
1576
+ from: state.inProgress ? pointToRendererPoint(state.from, this.transform) : state.from,
1577
+ to: state.inProgress ? pointToRendererPoint(state.to, this.transform) : state.to
1578
+ };
1579
+ },
1580
+ get domNode() {
1581
+ return domNode();
1582
+ },
1583
+ get dragging() {
1584
+ return dragging();
1585
+ },
1586
+ get edgeTypes() {
1587
+ return { ...InitialEdgeTypesMap, ...this._edgeTypes };
1588
+ },
1589
+ get elementsSelectable() {
1590
+ return elementsSelectable();
1591
+ },
1592
+ get height() {
1593
+ return height();
1594
+ },
1595
+ get lib() {
1596
+ return "solid";
1597
+ },
1598
+ get onError() {
1599
+ return config().onFlowError;
1600
+ },
1601
+ get maxZoom() {
1602
+ return maxZoom();
1603
+ },
1604
+ get minZoom() {
1605
+ return minZoom();
1606
+ },
1607
+ get nodes() {
1608
+ return nodesMemo.get();
1609
+ },
1610
+ get nodesConnectable() {
1611
+ return nodesConnectable();
1612
+ },
1613
+ get nodesDraggable() {
1614
+ return nodesDraggable();
1615
+ },
1616
+ get nodeTypes() {
1617
+ return { ...InitialNodeTypesMap, ...this._nodeTypes };
1618
+ },
1619
+ get panZoom() {
1620
+ return panZoom();
1621
+ },
1622
+ get selectedNodes() {
1623
+ return config().nodes.filter((node) => node.selected);
1624
+ },
1625
+ get selectedEdges() {
1626
+ return config().edges.filter((edge) => edge.selected);
1627
+ },
1628
+ get selectionRect() {
1629
+ return selectionRect();
1630
+ },
1631
+ get selectionRectMode() {
1632
+ return selectionRectMode();
1633
+ },
1634
+ get snapGrid() {
1635
+ return snapGrid();
1636
+ },
1637
+ get viewport() {
1638
+ return viewportMemo.get();
1639
+ },
1640
+ get viewportInitialized() {
1641
+ return panZoom() !== null;
1642
+ },
1643
+ get visibleEdgeIds() {
1644
+ return visibleEdgeIds();
1645
+ },
1646
+ get visibleNodeIds() {
1647
+ return visibleNodeIds();
1648
+ },
1649
+ get visibleNodesMap() {
1650
+ return visibleNodesMap();
1651
+ },
1652
+ get transform() {
1653
+ return transform();
1654
+ },
1655
+ get translateExtent() {
1656
+ return translateExtent();
1657
+ },
1658
+ get width() {
1659
+ return width();
1660
+ },
1661
+ // key press flags
1662
+ get selectionKeyPressed() {
1663
+ return selectionKeyPressed();
1664
+ },
1665
+ get multiselectionKeyPressed() {
1666
+ return multiselectionKeyPressed();
1667
+ },
1668
+ get deleteKeyPressed() {
1669
+ return deleteKeyPressed();
1670
+ },
1671
+ get panActivationKeyPressed() {
1672
+ return panActivationKeyPressed();
1673
+ },
1674
+ get zoomActivationKeyPressed() {
1675
+ return zoomActivationKeyPressed();
1676
+ }
1677
+ });
1678
+ const visibleNodesMap = createMemo5(() => {
1679
+ return nodeLookup;
1680
+ });
1681
+ const visibleNodeIds = createMemo5(() => {
1682
+ return Array.from(visibleNodesMap().values()).map((edge) => edge.id);
1683
+ });
1684
+ const visibleEdgeIds = createMemo5(() => {
1685
+ return Array.from(layoutedEdgesMap.values()).map((edge) => edge.id);
1686
+ });
1687
+ const getEdge = (id) => layoutedEdgesMap.get(id);
1688
+ const fitView = async (options) => {
1689
+ if (!store.panZoom) return false;
1690
+ return fitViewport(
1691
+ {
1692
+ nodes: nodeLookup,
1693
+ width: store.width,
1694
+ height: store.height,
1695
+ panZoom: store.panZoom,
1696
+ minZoom: store.minZoom,
1697
+ maxZoom: store.maxZoom
1698
+ },
1699
+ options ?? config().fitViewOptions
1700
+ );
1701
+ };
1702
+ const resetStoreValues = () => {
1703
+ setDragging(false);
1704
+ setSelectionRect(void 0);
1705
+ setSelectionRectMode(void 0);
1706
+ setSelectionKeyPressed(false);
1707
+ setMultiselectionKeyPressed(false);
1708
+ setDeleteKeyPressed(false);
1709
+ setPanActivationKeyPressed(false);
1710
+ setZoomActivationKeyPressed(false);
1711
+ setConnection({ ...initialConnection });
1712
+ setClickConnectStartHandle(void 0);
1713
+ viewportMemo.set(config().initialViewport ?? { x: 0, y: 0, zoom: 1 });
1714
+ setAriaLiveMessage("");
1715
+ setSnapGrid(void 0);
1716
+ };
1717
+ const addEdge2 = (edgeParams) => {
1718
+ edgesMemo.set((edges) => systemAddEdge(edgeParams, edges));
1719
+ };
1720
+ let initialFitViewApplied = false;
1721
+ const applyInitialFitView = (initialFitView) => {
1722
+ initialFitViewApplied = !initialFitView;
1723
+ };
1724
+ const updateNodePositions = (nodeDragItems, dragging2 = false) => {
1725
+ nodesMemo.set(
1726
+ (node) => nodeDragItems.has(node.id),
1727
+ produce((node) => {
1728
+ node.dragging = dragging2;
1729
+ node.position = nodeDragItems.get(node.id).position;
1730
+ })
1731
+ );
1732
+ };
1733
+ let pendingEntries = void 0;
1734
+ const requestUpdateNodeInternals = (updateEntries) => {
1735
+ if (pendingEntries) {
1736
+ pendingEntries.push(...updateEntries);
1737
+ return;
1738
+ }
1739
+ pendingEntries = updateEntries;
1740
+ requestIdleCallback(() => {
1741
+ batch2(() => {
1742
+ const updates = new Map(pendingEntries);
1743
+ pendingEntries = void 0;
1744
+ const { changes, updatedInternals } = systemUpdateNodeInternals(
1745
+ updates,
1746
+ nodeLookup,
1747
+ parentLookup,
1748
+ store.domNode,
1749
+ store.nodeOrigin
1750
+ );
1751
+ if (!updatedInternals) return;
1752
+ updateAbsolutePositions(nodeLookup, parentLookup, {
1753
+ nodeOrigin: store.nodeOrigin,
1754
+ nodeExtent: store.nodeExtent
1755
+ });
1756
+ const nodeToChange = changes.reduce(
1757
+ (acc, change) => {
1758
+ const node = nodeLookup.get(change.id)?.internals.userNode;
1759
+ if (!node) return acc;
1760
+ acc.set(node.id, change);
1761
+ return acc;
1762
+ },
1763
+ /* @__PURE__ */ new Map()
1764
+ );
1765
+ nodesMemo.set(
1766
+ (node) => nodeToChange.has(node.id),
1767
+ produce((node) => {
1768
+ const change = nodeToChange.get(node.id);
1769
+ switch (change.type) {
1770
+ case "dimensions": {
1771
+ if (change.setAttributes) {
1772
+ node.width = change.dimensions?.width ?? node.width;
1773
+ node.height = change.dimensions?.height ?? node.height;
1774
+ }
1775
+ node.measured = { ...node.measured, ...change.dimensions };
1776
+ break;
1777
+ }
1778
+ case "position":
1779
+ node.position = change.position ?? node.position;
1780
+ break;
1781
+ }
1782
+ })
1783
+ );
1784
+ if (!initialFitViewApplied) {
1785
+ initialFitViewApplied = true;
1786
+ void fitView();
1787
+ }
1788
+ });
1789
+ });
1790
+ };
1791
+ const zoomBy = async (factor, options) => {
1792
+ return store.panZoom ? store.panZoom.scaleBy(factor, options) : false;
1793
+ };
1794
+ const zoomIn = (options) => zoomBy(1.2, options);
1795
+ const zoomOut = (options) => zoomBy(1 / 1.2, options);
1796
+ const setCenter = async (x, y, options) => {
1797
+ const nextZoom = typeof options?.zoom !== "undefined" ? options.zoom : store.maxZoom;
1798
+ const currentPanZoom = store.panZoom;
1799
+ if (!currentPanZoom) {
1800
+ return Promise.resolve(false);
1801
+ }
1802
+ await currentPanZoom.setViewport(
1803
+ {
1804
+ x: store.width / 2 - x * nextZoom,
1805
+ y: store.height / 2 - y * nextZoom,
1806
+ zoom: nextZoom
1807
+ },
1808
+ { duration: options?.duration, ease: options?.ease, interpolate: options?.interpolate }
1809
+ );
1810
+ return Promise.resolve(true);
1811
+ };
1812
+ const setPaneClickDistance = (distance) => {
1813
+ store.panZoom?.setClickDistance(distance);
1814
+ };
1815
+ const unselectNodesAndEdges = ({
1816
+ nodes: _nodes,
1817
+ edges
1818
+ } = {}) => {
1819
+ const nodesToUnselect = new Set((_nodes ? _nodes : store.nodes).map(({ id }) => id));
1820
+ if (nodesToUnselect.size) {
1821
+ nodesMemo.set(
1822
+ (node) => nodesToUnselect.has(node.id),
1823
+ produce((node) => {
1824
+ node.selected = false;
1825
+ })
1826
+ );
1827
+ }
1828
+ const edgesToUnselect = new Set((edges ? edges : store.edges).map(({ id }) => id));
1829
+ if (edgesToUnselect.size) {
1830
+ edgesMemo.set(
1831
+ (edge) => edgesToUnselect.has(edge.id),
1832
+ produce((edge) => {
1833
+ edge.selected = false;
1834
+ })
1835
+ );
1836
+ }
1837
+ };
1838
+ const addSelectedNodes = (ids) => {
1839
+ const isMultiSelection = store.multiselectionKeyPressed;
1840
+ const selectState = /* @__PURE__ */ new Map();
1841
+ nodesMemo.set(
1842
+ (node) => {
1843
+ const nodeWillBeSelected = ids.includes(node.id);
1844
+ const selected = isMultiSelection ? node.selected || nodeWillBeSelected : nodeWillBeSelected;
1845
+ selectState.set(node.id, selected);
1846
+ return node.selected !== selected;
1847
+ },
1848
+ produce((node) => {
1849
+ const internalNode = nodeLookup.get(node.id);
1850
+ if (internalNode) internalNode.selected = selectState.get(node.id);
1851
+ node.selected = selectState.get(node.id);
1852
+ })
1853
+ );
1854
+ if (!isMultiSelection) {
1855
+ unselectNodesAndEdges({ nodes: [] });
1856
+ }
1857
+ };
1858
+ const addSelectedEdges = (ids) => {
1859
+ const isMultiSelection = store.multiselectionKeyPressed;
1860
+ const edgeSelectState = /* @__PURE__ */ new Map();
1861
+ edgesMemo.set(
1862
+ (edge) => {
1863
+ const edgeWillBeSelected = ids.includes(edge.id);
1864
+ const selected = isMultiSelection ? edge.selected || edgeWillBeSelected : edgeWillBeSelected;
1865
+ edgeSelectState.set(edge.id, selected);
1866
+ return edge.selected !== selected;
1867
+ },
1868
+ produce((edge) => {
1869
+ edge.selected = edgeSelectState.get(edge.id);
1870
+ })
1871
+ );
1872
+ if (!isMultiSelection) {
1873
+ unselectNodesAndEdges({ edges: [] });
1874
+ }
1875
+ };
1876
+ const handleNodeSelection = (id, unselect, nodeRef) => {
1877
+ const node = store.nodes.find((n) => n.id === id);
1878
+ if (!node) {
1879
+ return;
1880
+ }
1881
+ batch2(() => {
1882
+ setSelectionRect(void 0);
1883
+ setSelectionRectMode(void 0);
1884
+ });
1885
+ if (!node.selected) {
1886
+ addSelectedNodes([id]);
1887
+ } else if (unselect || node.selected && store.multiselectionKeyPressed) {
1888
+ unselectNodesAndEdges({ nodes: [node], edges: [] });
1889
+ requestAnimationFrame(() => nodeRef?.blur());
1890
+ }
1891
+ };
1892
+ const handleEdgeSelection = (id) => {
1893
+ const edge = edgeLookup.get(id);
1894
+ if (!edge) {
1895
+ return;
1896
+ }
1897
+ const selectable = edge.selectable || store.elementsSelectable && typeof edge.selectable === "undefined";
1898
+ if (!selectable) return;
1899
+ batch2(() => {
1900
+ setSelectionRect(void 0);
1901
+ setSelectionRectMode(void 0);
1902
+ });
1903
+ if (!edge.selected) {
1904
+ addSelectedEdges([id]);
1905
+ } else if (edge.selected && store.multiselectionKeyPressed) {
1906
+ unselectNodesAndEdges({ nodes: [], edges: [edge] });
1907
+ }
1908
+ };
1909
+ const moveSelectedNodes = (direction, factor) => {
1910
+ const nodeUpdates = /* @__PURE__ */ new Map();
1911
+ const xVelo = store.snapGrid?.[0] ?? 5;
1912
+ const yVelo = store.snapGrid?.[1] ?? 5;
1913
+ const xDiff = direction.x * xVelo * factor;
1914
+ const yDiff = direction.y * yVelo * factor;
1915
+ for (const node of nodeLookup.values()) {
1916
+ const isSelected = node.selected && (node.draggable || store.nodesDraggable && typeof node.draggable === "undefined");
1917
+ if (!isSelected) {
1918
+ continue;
1919
+ }
1920
+ let nextPosition = {
1921
+ x: node.internals.positionAbsolute.x + xDiff,
1922
+ y: node.internals.positionAbsolute.y + yDiff
1923
+ };
1924
+ if (store.snapGrid) {
1925
+ nextPosition = snapPosition(nextPosition, store.snapGrid);
1926
+ }
1927
+ const { position, positionAbsolute } = calculateNodePosition({
1928
+ nodeId: node.id,
1929
+ nextPosition,
1930
+ nodeLookup,
1931
+ nodeExtent: store.nodeExtent,
1932
+ nodeOrigin: store.nodeOrigin,
1933
+ onError: store.onError
1934
+ });
1935
+ node.position = position;
1936
+ node.internals.positionAbsolute = positionAbsolute;
1937
+ nodeUpdates.set(node.id, node);
1938
+ }
1939
+ updateNodePositions(nodeUpdates);
1940
+ };
1941
+ const panBy = (delta) => {
1942
+ return panBySystem({
1943
+ delta,
1944
+ panZoom: store.panZoom,
1945
+ transform: store.transform,
1946
+ translateExtent: store.translateExtent,
1947
+ width: store.width,
1948
+ height: store.height
1949
+ });
1950
+ };
1951
+ const cancelConnection = () => {
1952
+ setConnection({ ...initialConnection });
1953
+ };
1954
+ const reset = () => {
1955
+ resetStoreValues();
1956
+ unselectNodesAndEdges();
1957
+ };
1958
+ createEffect4(() => {
1959
+ store.panZoom?.syncViewport(store.viewport);
1960
+ });
1961
+ createEffect4(() => {
1962
+ const _panZoom = panZoom();
1963
+ if (!_panZoom) return;
1964
+ createEffect4(() => {
1965
+ _panZoom.setScaleExtent([store.minZoom, store.maxZoom]);
1966
+ });
1967
+ createEffect4(() => {
1968
+ _panZoom.setTranslateExtent(store.translateExtent);
1969
+ });
1970
+ });
1971
+ createComputed(
1972
+ mapArray(
1973
+ () => store.nodes,
1974
+ (userNode) => {
1975
+ createComputed(() => {
1976
+ const internalNode = untrack(() => nodeLookup.get(userNode.id));
1977
+ const selectedNodeZ = store.elevateNodesOnSelect ? 1e3 : 0;
1978
+ const clampedPosition = clampPosition2(
1979
+ getNodePositionWithOrigin2(userNode, store.nodeOrigin),
1980
+ isCoordinateExtent2(userNode.extent) ? userNode.extent : store.nodeExtent,
1981
+ getNodeDimensions2(userNode)
1982
+ );
1983
+ const preservedMeasured = {
1984
+ width: userNode.measured?.width ?? internalNode?.measured?.width,
1985
+ height: userNode.measured?.height ?? internalNode?.measured?.height
1986
+ };
1987
+ const updatedNodeInternals = {
1988
+ ...userNode,
1989
+ measured: preservedMeasured,
1990
+ internals: {
1991
+ positionAbsolute: clampedPosition,
1992
+ // If there is neither a user-provided nor a previously measured size,
1993
+ // reset handleBounds so that the node gets re-measured.
1994
+ handleBounds: !userNode.measured && !internalNode?.measured ? void 0 : internalNode?.internals.handleBounds,
1995
+ z: calculateZ(userNode, selectedNodeZ),
1996
+ userNode
1997
+ }
1998
+ };
1999
+ nodeLookup.set(userNode.id, updatedNodeInternals);
2000
+ if (userNode.parentId) {
2001
+ updateChildNode(updatedNodeInternals, nodeLookup, parentLookup, {
2002
+ nodeOrigin: store.nodeOrigin,
2003
+ nodeExtent: store.nodeExtent,
2004
+ elevateNodesOnSelect: store.elevateNodesOnSelect,
2005
+ checkEquality: true
2006
+ });
2007
+ }
2008
+ });
2009
+ onCleanup2(() => {
2010
+ });
2011
+ }
2012
+ )
2013
+ );
2014
+ createEffect4(() => {
2015
+ const currentIds = new Set(store.nodes.map((n) => n.id));
2016
+ for (const id of Array.from(nodeLookup.keys())) {
2017
+ if (!currentIds.has(id)) {
2018
+ nodeLookup.delete(id);
2019
+ }
2020
+ }
2021
+ });
2022
+ createComputed(
2023
+ mapArray(
2024
+ () => store.edges,
2025
+ (edge) => {
2026
+ const {
2027
+ source: sourceNodeId,
2028
+ target: targetNodeId,
2029
+ sourceHandle = null,
2030
+ targetHandle = null
2031
+ } = edge;
2032
+ const connection2 = {
2033
+ edgeId: edge.id,
2034
+ source: sourceNodeId,
2035
+ target: targetNodeId,
2036
+ sourceHandle,
2037
+ targetHandle
2038
+ };
2039
+ const sourceKey = `${sourceNodeId}-${sourceHandle}--${targetNodeId}-${targetHandle}`;
2040
+ const targetKey = `${targetNodeId}-${targetHandle}--${sourceNodeId}-${sourceHandle}`;
2041
+ createComputed(() => {
2042
+ batch2(() => {
2043
+ addConnectionToLookup(
2044
+ "source",
2045
+ connection2,
2046
+ targetKey,
2047
+ connectionLookup,
2048
+ sourceNodeId,
2049
+ sourceHandle
2050
+ );
2051
+ addConnectionToLookup(
2052
+ "target",
2053
+ connection2,
2054
+ sourceKey,
2055
+ connectionLookup,
2056
+ targetNodeId,
2057
+ targetHandle
2058
+ );
2059
+ edgeLookup.set(edge.id, edge);
2060
+ });
2061
+ });
2062
+ createComputed(() => {
2063
+ const sourceNode = nodeLookup.get(edge.source);
2064
+ const targetNode = nodeLookup.get(edge.target);
2065
+ if (!sourceNode || !targetNode) return;
2066
+ if (store.onlyRenderVisibleElements) {
2067
+ const edgeVisible = isEdgeVisible({
2068
+ sourceNode,
2069
+ targetNode,
2070
+ width: store.width ?? 0,
2071
+ height: store.height ?? 0,
2072
+ transform: store.transform
2073
+ });
2074
+ if (!edgeVisible) return;
2075
+ store.visibleNodesMap.set(sourceNode.id, sourceNode);
2076
+ store.visibleNodesMap.set(targetNode.id, targetNode);
2077
+ }
2078
+ const edgePosition = getEdgePosition({
2079
+ id: edge.id,
2080
+ sourceNode,
2081
+ targetNode,
2082
+ sourceHandle: edge.sourceHandle || null,
2083
+ targetHandle: edge.targetHandle || null,
2084
+ connectionMode: store.connectionMode,
2085
+ onError: store.onError
2086
+ });
2087
+ if (!edgePosition) return;
2088
+ layoutedEdgesMap.set(edge.id, {
2089
+ ...store.defaultEdgeOptions,
2090
+ ...edge,
2091
+ ...edgePosition,
2092
+ zIndex: getElevatedEdgeZIndex({
2093
+ selected: edge.selected,
2094
+ zIndex: edge.zIndex ?? store.defaultEdgeOptions.zIndex,
2095
+ sourceNode,
2096
+ targetNode,
2097
+ elevateOnSelect: store.elevateEdgesOnSelect
2098
+ }),
2099
+ sourceNode,
2100
+ targetNode,
2101
+ edge
2102
+ });
2103
+ });
2104
+ onCleanup2(() => {
2105
+ batch2(() => {
2106
+ edgeLookup.delete(edge.id);
2107
+ layoutedEdgesMap.delete(edge.id);
2108
+ removeConnectionFromLookup(
2109
+ "source",
2110
+ targetKey,
2111
+ connectionLookup,
2112
+ sourceNodeId,
2113
+ sourceHandle
2114
+ );
2115
+ removeConnectionFromLookup(
2116
+ "target",
2117
+ sourceKey,
2118
+ connectionLookup,
2119
+ targetNodeId,
2120
+ targetHandle
2121
+ );
2122
+ });
2123
+ });
2124
+ }
2125
+ )
2126
+ );
2127
+ createEffect4(() => {
2128
+ const currentIds = new Set(store.edges.map((e) => e.id));
2129
+ for (const id of Array.from(edgeLookup.keys())) {
2130
+ if (!currentIds.has(id)) {
2131
+ edgeLookup.delete(id);
2132
+ connectionLookup.delete(id);
2133
+ layoutedEdgesMap.delete(id);
2134
+ }
2135
+ }
2136
+ });
2137
+ return {
2138
+ store,
2139
+ nodeLookup,
2140
+ edgeLookup,
2141
+ parentLookup,
2142
+ connectionLookup,
2143
+ actions: {
2144
+ getEdge,
2145
+ applyInitialFitView,
2146
+ resetStoreValues,
2147
+ requestUpdateNodeInternals,
2148
+ setAriaLabelConfig,
2149
+ setAriaLiveMessage,
2150
+ setClickConnectStartHandle,
2151
+ setConfig,
2152
+ setConnection,
2153
+ setDeleteKeyPressed,
2154
+ setDomNode,
2155
+ setDragging,
2156
+ get setEdges() {
2157
+ return edgesMemo.set;
2158
+ },
2159
+ setElementsSelectable,
2160
+ setHeight,
2161
+ setMultiselectionKeyPressed,
2162
+ get setNodes() {
2163
+ return nodesMemo.set;
2164
+ },
2165
+ setNodesConnectable,
2166
+ setNodesDraggable,
2167
+ setPanActivationKeyPressed,
2168
+ setPanZoom,
2169
+ setSelectionKeyPressed,
2170
+ setSelectionRect,
2171
+ setSelectionRectMode,
2172
+ get setViewport() {
2173
+ return viewportMemo.set;
2174
+ },
2175
+ setWidth,
2176
+ setZoomActivationKeyPressed,
2177
+ // Port Svelte Flow Actions to Solid Flow
2178
+ addEdge: addEdge2,
2179
+ updateNodePositions,
2180
+ zoomIn,
2181
+ zoomOut,
2182
+ fitView,
2183
+ setCenter,
2184
+ setPaneClickDistance,
2185
+ unselectNodesAndEdges,
2186
+ addSelectedNodes,
2187
+ addSelectedEdges,
2188
+ handleNodeSelection,
2189
+ handleEdgeSelection,
2190
+ moveSelectedNodes,
2191
+ panBy,
2192
+ cancelConnection,
2193
+ reset
2194
+ }
2195
+ };
2196
+ };
2197
+
2198
+ // src/components/contexts/flow.tsx
2199
+ var SolidFlowContext = createContext4();
2200
+ function useInternalSolidFlow() {
2201
+ const ctx = useContext4(SolidFlowContext);
2202
+ if (!ctx) {
2203
+ throw new Error(
2204
+ "solid-flow: Your application must be wrapped with <SolidFlow> in order to invoke useInternalSolidFlow within your components"
2205
+ );
2206
+ }
2207
+ return ctx;
2208
+ }
2209
+
2210
+ // src/components/graph/marker/Marker.tsx
2211
+ import { mergeProps as mergeProps9, Show as Show7 } from "solid-js";
2212
+ var Marker = (props) => {
2213
+ const _props = mergeProps9(
2214
+ {
2215
+ markerUnits: "strokeWidth",
2216
+ orient: "auto-start-reverse",
2217
+ width: 12.5,
2218
+ height: 12.5,
2219
+ color: "none"
2220
+ },
2221
+ props
2222
+ );
2223
+ const color = () => _props.color ?? "var(--xy-edge-stroke)";
2224
+ return <marker
2225
+ class="solid-flow__arrowhead"
2226
+ id={_props.id}
2227
+ markerWidth={_props.width}
2228
+ markerHeight={_props.height}
2229
+ viewBox="-10 -10 20 20"
2230
+ markerUnits={_props.markerUnits}
2231
+ orient={_props.orient}
2232
+ refX="0"
2233
+ refY="0"
2234
+ >
2235
+ <Show7
2236
+ when={_props.type === "arrow"}
2237
+ fallback={<polyline
2238
+ class="arrowclosed"
2239
+ stroke={color()}
2240
+ fill={color()}
2241
+ stroke-linecap="round"
2242
+ stroke-linejoin="round"
2243
+ stroke-width={_props.strokeWidth}
2244
+ points="-5,-4 0,0 -5,4 -5,-4"
2245
+ />}
2246
+ >
2247
+ <polyline
2248
+ class="arrow"
2249
+ stroke={color()}
2250
+ fill="none"
2251
+ stroke-linecap="round"
2252
+ stroke-linejoin="round"
2253
+ stroke-width={_props.strokeWidth}
2254
+ points="-5,-4 0,0 -5,4"
2255
+ />
2256
+ </Show7>
2257
+ </marker>;
2258
+ };
2259
+
2260
+ // src/components/graph/marker/MarkerDefinition.tsx
2261
+ import { createMarkerIds } from "@xyflow/system";
2262
+ import { createMemo as createMemo6, For, Show as Show8 } from "solid-js";
2263
+ var MarkerDefinition = () => {
2264
+ const { store } = useInternalSolidFlow();
2265
+ const markers = createMemo6(() => {
2266
+ return createMarkerIds(store.edges, {
2267
+ id: store.id,
2268
+ defaultColor: store.defaultMarkerColor,
2269
+ defaultMarkerStart: store.defaultEdgeOptions.markerStart,
2270
+ defaultMarkerEnd: store.defaultEdgeOptions.markerEnd
2271
+ });
2272
+ });
2273
+ return <Show8 when={markers().length > 0}>
67
2274
  <svg class="solid-flow__marker">
68
2275
  <defs>
69
- <Es each={o()}>{t=><Wo{...t}/>}</Es>
2276
+ <For each={markers()}>{(marker) => <Marker {...marker} />}</For>
70
2277
  </defs>
71
2278
  </svg>
72
- </Cs>};var $o=e=>{let{store:o}=z();return<div class="solid-flow__edges">
73
- <Zo/>
74
-
75
- <Ts each={o.visibleEdgeIds}>
76
- {t=><Io edgeId={t}onEdgeClick={e.onEdgeClick}onEdgeContextMenu={e.onEdgeContextMenu}onEdgePointerEnter={e.onEdgePointerEnter}onEdgePointerLeave={e.onEdgePointerLeave}/>}
77
- </Ts>
78
- </div>};import{For as Ms,onCleanup as Is}from"solid-js";var Uo=e=>{let{actions:o,store:t}=z(),N=new ResizeObserver(S=>{o.requestUpdateNodeInternals(S.map(P=>{let x=P.target.getAttribute("data-id");return[x,{id:x,nodeElement:P.target,force:!0}]}))});return Is(()=>{N.disconnect()}),<div class="solid-flow__container solid-flow__nodes">
79
- <Ms each={t.visibleNodeIds}>
80
- {S=><Ho nodeId={S}resizeObserver={N}nodeClickDistance={e.nodeClickDistance}onNodeClick={e.onNodeClick}onNodePointerEnter={e.onNodePointerEnter}onNodePointerMove={e.onNodePointerMove}onNodePointerLeave={e.onNodePointerLeave}onNodeDrag={e.onNodeDrag}onNodeDragStart={e.onNodeDragStart}onNodeDragStop={e.onNodeDragStop}onNodeContextMenu={e.onNodeContextMenu}/>}
81
- </Ms>
82
- </div>};import{getEventPosition as mn,getNodesInside as ks,SelectionMode as Ds}from"@xyflow/system";import Os from"clsx";import{batch as Ge}from"solid-js";import{produce as un}from"solid-js/store";var yn=(e,o)=>{if(e.size!==o.size)return!1;for(let t of e)if(!o.has(t))return!1;return!0},Jo=e=>{let{store:o,nodeLookup:t,edgeLookup:N,connectionLookup:S,actions:P}=z(),x,b=null,C=!1,T=new Set,v=new Set,E=()=>o.panActivationKeyPressed||e.panOnDrag,w=()=>o.selectionKeyPressed||o.selectionRect||e.selectionOnDrag&&E()!==!0,I=()=>o.elementsSelectable&&(w()||o.selectionRectMode==="user"),D=_=>{if(_.target===x){if(C){C=!1;return}e.onPaneClick?.({event:_}),Ge(()=>{P.unselectNodesAndEdges(),P.setSelectionRectMode(void 0)})}},k=_=>{if(b=x?.getBoundingClientRect()??null,!o.elementsSelectable||!w()||_.button!==0||_.target!==x||!b)return;_.target?.setPointerCapture?.(_.pointerId);let{x:$,y:ee}=mn(_,b);Ge(()=>{P.unselectNodesAndEdges(),P.setSelectionRect({width:0,height:0,startX:$,startY:ee,x:$,y:ee})})},R=_=>{if(!w()||!b||!o.selectionRect)return;C=!0;let $=mn(_,b),{startX:ee=0,startY:ie=0}=o.selectionRect,de={...o.selectionRect,x:$.x<ee?$.x:ee,y:$.y<ie?$.y:ie,width:Math.abs($.x-ee),height:Math.abs($.y-ie)},U=T,G=v;T=new Set(ks(t,de,o.transform,o.selectionMode===Ds.Partial,!0).map(F=>F.id));let O=o.defaultEdgeOptions.selectable??!0;v=new Set;for(let F of T){let K=S.get(F);if(K)for(let{edgeId:Z}of K.values()){let te=N.get(Z);te&&(te.selectable??O)&&v.add(Z)}}Ge(()=>{if(!yn(U,T)){let F=new Map;P.setNodes(K=>{let Z=T.has(K.id);return F.set(K.id,Z),!!K.selected!==Z},un(K=>{K.selected=F.get(K.id)}))}if(!yn(G,v)){let F=new Map;P.setEdges(K=>{let Z=v.has(K.id);return F.set(K.id,Z),!!K.selected!==Z},un(K=>{K.selected=F.get(K.id)}))}P.setSelectionRectMode("user"),P.setSelectionRect(de)})},Y=_=>{_.button===0&&(_.target?.releasePointerCapture?.(_.pointerId),!w()&&o.selectionRectMode==="user"&&_.target===x&&D(_),Ge(()=>{P.setSelectionRect(void 0),T.size>0&&P.setSelectionRectMode("nodes")}),o.selectionKeyPressed&&(C=!1),e.onSelectionEnd?.(_))},H=_=>{if(_.target!==x)return;let $=E();if(Array.isArray($)&&$.includes(2)){_.preventDefault();return}e.onPaneContextMenu?.({event:_})};return<div ref={x}class={Os("solid-flow__container solid-flow__pane",{selection:w(),dragging:o.dragging,draggable:e.panOnDrag===!0||Array.isArray(e.panOnDrag)&&e.panOnDrag.includes(0)})}onClick={_=>I()?void 0:D(_)}onPointerDown={_=>I()?k(_):void 0}onPointerMove={_=>I()?R(_):void 0}onPointerUp={_=>I()?Y(_):void 0}onContextMenu={H}>
83
- {e.children}
84
- </div>};import zs from"clsx";import{mergeProps as Rs,splitProps as As}from"solid-js";var Pe=e=>{let{store:o}=z(),t=Rs({position:"top-right",style:{}},e),[N,S]=As(t,["class","position","style","children"]);return<div class={zs(["solid-flow__panel",...N.position.split("-"),N.class])}style={{"pointer-events":o.selectionRectMode?"none":void 0,...N.style}}{...S}>
85
- {N.children}
86
- </div>};var Go=e=>{let{store:o}=z();return<div class="solid-flow__container solid-flow__viewport xyflow__viewport"style={{transform:`translate(${o.viewport.x}px, ${o.viewport.y}px) scale(${o.viewport.zoom})`}}>
87
- {e.children}
88
- </div>};import{Show as _s}from"solid-js";import{Portal as Ls}from"solid-js/web";var Hs=e=>{let{store:o}=z();return<_s when={o.domNode}>
89
- {t=><Ls mount={t().querySelector(".solid-flow__viewport-portal")??void 0}>
90
- {e.children}
91
- </Ls>}
92
- </_s>};import{XYPanZoom as Bs}from"@xyflow/system";import{batch as Vs,createEffect as Ks,onMount as Xs}from"solid-js";var Qo=e=>{let o,{store:t,actions:N}=z(),S=()=>e.initialViewport||{x:0,y:0,zoom:1},P=()=>t.panActivationKeyPressed||e.panOnDrag,x=()=>t.panActivationKeyPressed||e.panOnScroll,b=C=>{let[T,v,E]=C;N.setViewport({x:T,y:v,zoom:E})};return Xs(()=>{let C=Bs({domNode:o,minZoom:t.minZoom,maxZoom:t.maxZoom,translateExtent:t.translateExtent,viewport:S(),paneClickDistance:e.paneClickDistance,onDraggingChange:N.setDragging,onPanZoomStart:e.onMoveStart,onPanZoom:e.onMove,onPanZoomEnd:e.onMoveEnd}),T=C.getViewport();(S().x!==T.x||S().y!==T.y||S().zoom!==T.zoom)&&b([T.x,T.y,T.zoom]),Vs(()=>{N.setViewport(T),N.setPanZoom(C)}),e.onViewportInitialized?.(),Ks(()=>{C.update({lib:t.lib,zoomActivationKeyPressed:t.zoomActivationKeyPressed,noPanClassName:t.noPanClass,noWheelClassName:t.noWheelClass,userSelectionActive:!!t.selectionRect,panOnScrollSpeed:.5,panOnDrag:P(),panOnScroll:x(),zoomOnScroll:e.zoomOnScroll,zoomOnDoubleClick:e.zoomOnDoubleClick,zoomOnPinch:e.zoomOnPinch,panOnScrollMode:e.panOnScrollMode,preventScrolling:typeof e.preventScrolling=="boolean"?e.preventScrolling:!0,onTransformChange:b})})}),<div ref={o}class="solid-flow__container solid-flow__zoom">
93
- {e.children}
94
- </div>};import{getBezierPath as Fs,getConnectionStatus as Ys,getSmoothStepPath as Ws,getStraightPath as Zs}from"@xyflow/system";import $s from"clsx";import{Show as Sn}from"solid-js";var Us=e=>{let{store:o}=z(),t=()=>Ys(o.connection.isValid);return<Sn when={o.connection.inProgress}>
95
- <svg class="solid-flow__container solid-flow__connectionline"width={o.width}height={o.height}style={e.containerStyle}>
96
- <g class={$s(["solid-flow__connection",t()])}>
97
- <Sn when={e.component}fallback={<Js style={e.style}/>}>
98
- {N=>{let S=N();return<S connectionLineType={o.connectionLineType}connectionLineStyle={e.style}fromNode={o.connection.fromNode}fromHandle={o.connection.fromHandle}fromX={o.connection.from.x}fromY={o.connection.from.y}toX={o.connection.to.x}toY={o.connection.to.y}fromPosition={o.connection.fromPosition}toPosition={o.connection.toPosition}connectionStatus={t()}toNode={o.connection.toNode}toHandle={o.connection.toHandle}/>}}
99
- </Sn>
2279
+ </Show8>;
2280
+ };
2281
+
2282
+ // src/components/container/EdgeRenderer.tsx
2283
+ var EdgeRenderer = (props) => {
2284
+ const { store } = useInternalSolidFlow();
2285
+ return <div class="solid-flow__edges">
2286
+ <MarkerDefinition />
2287
+
2288
+ <For2 each={store.visibleEdgeIds}>
2289
+ {(edgeId) => {
2290
+ return <EdgeWrapper
2291
+ edgeId={edgeId}
2292
+ onEdgeClick={props.onEdgeClick}
2293
+ onEdgeContextMenu={props.onEdgeContextMenu}
2294
+ onEdgePointerEnter={props.onEdgePointerEnter}
2295
+ onEdgePointerLeave={props.onEdgePointerLeave}
2296
+ />;
2297
+ }}
2298
+ </For2>
2299
+ </div>;
2300
+ };
2301
+
2302
+ // src/components/container/NodeRenderer.tsx
2303
+ import { For as For3, onCleanup as onCleanup3 } from "solid-js";
2304
+ var NodeRenderer = (props) => {
2305
+ const { actions, store } = useInternalSolidFlow();
2306
+ const resizeObserver = new ResizeObserver((entries) => {
2307
+ actions.requestUpdateNodeInternals(
2308
+ entries.map((entry) => {
2309
+ const id = entry.target.getAttribute("data-id");
2310
+ return [
2311
+ id,
2312
+ {
2313
+ id,
2314
+ nodeElement: entry.target,
2315
+ force: true
2316
+ }
2317
+ ];
2318
+ })
2319
+ );
2320
+ });
2321
+ onCleanup3(() => {
2322
+ resizeObserver.disconnect();
2323
+ });
2324
+ return <div class="solid-flow__container solid-flow__nodes">
2325
+ <For3 each={store.visibleNodeIds}>
2326
+ {(nodeId) => {
2327
+ return <NodeWrapper
2328
+ nodeId={nodeId}
2329
+ resizeObserver={resizeObserver}
2330
+ nodeClickDistance={props.nodeClickDistance}
2331
+ onNodeClick={props.onNodeClick}
2332
+ onNodePointerEnter={props.onNodePointerEnter}
2333
+ onNodePointerMove={props.onNodePointerMove}
2334
+ onNodePointerLeave={props.onNodePointerLeave}
2335
+ onNodeDrag={props.onNodeDrag}
2336
+ onNodeDragStart={props.onNodeDragStart}
2337
+ onNodeDragStop={props.onNodeDragStop}
2338
+ onNodeContextMenu={props.onNodeContextMenu}
2339
+ />;
2340
+ }}
2341
+ </For3>
2342
+ </div>;
2343
+ };
2344
+
2345
+ // src/components/container/Pane.tsx
2346
+ import { getEventPosition, getNodesInside as getNodesInside3, SelectionMode } from "@xyflow/system";
2347
+ import clsx7 from "clsx";
2348
+ import { batch as batch3 } from "solid-js";
2349
+ import { produce as produce2 } from "solid-js/store";
2350
+ var isSetEqual = (a, b) => {
2351
+ if (a.size !== b.size) return false;
2352
+ for (const item of a) {
2353
+ if (!b.has(item)) {
2354
+ return false;
2355
+ }
2356
+ }
2357
+ return true;
2358
+ };
2359
+ var Pane = (props) => {
2360
+ const { store, nodeLookup, edgeLookup, connectionLookup, actions } = useInternalSolidFlow();
2361
+ let container;
2362
+ let containerBounds = null;
2363
+ let selectionInProgress = false;
2364
+ let selectedNodeIds = /* @__PURE__ */ new Set();
2365
+ let selectedEdgeIds = /* @__PURE__ */ new Set();
2366
+ const _panOnDrag = () => store.panActivationKeyPressed || props.panOnDrag;
2367
+ const isSelecting = () => store.selectionKeyPressed || store.selectionRect || props.selectionOnDrag && _panOnDrag() !== true;
2368
+ const hasActiveSelection = () => store.elementsSelectable && (isSelecting() || store.selectionRectMode === "user");
2369
+ const onClick = (event) => {
2370
+ if (event.target !== container) return;
2371
+ if (selectionInProgress) {
2372
+ selectionInProgress = false;
2373
+ return;
2374
+ }
2375
+ props.onPaneClick?.({ event });
2376
+ batch3(() => {
2377
+ actions.unselectNodesAndEdges();
2378
+ actions.setSelectionRectMode(void 0);
2379
+ });
2380
+ };
2381
+ const onPointerDown = (event) => {
2382
+ containerBounds = container?.getBoundingClientRect() ?? null;
2383
+ if (!store.elementsSelectable || !isSelecting() || event.button !== 0 || event.target !== container || !containerBounds) {
2384
+ return;
2385
+ }
2386
+ event.target?.setPointerCapture?.(event.pointerId);
2387
+ const { x, y } = getEventPosition(event, containerBounds);
2388
+ batch3(() => {
2389
+ actions.unselectNodesAndEdges();
2390
+ actions.setSelectionRect({
2391
+ width: 0,
2392
+ height: 0,
2393
+ startX: x,
2394
+ startY: y,
2395
+ x,
2396
+ y
2397
+ });
2398
+ });
2399
+ };
2400
+ const onPointerMove = (event) => {
2401
+ if (!isSelecting() || !containerBounds || !store.selectionRect) {
2402
+ return;
2403
+ }
2404
+ selectionInProgress = true;
2405
+ const mousePos = getEventPosition(event, containerBounds);
2406
+ const { startX = 0, startY = 0 } = store.selectionRect;
2407
+ const nextUserSelectRect = {
2408
+ ...store.selectionRect,
2409
+ x: mousePos.x < startX ? mousePos.x : startX,
2410
+ y: mousePos.y < startY ? mousePos.y : startY,
2411
+ width: Math.abs(mousePos.x - startX),
2412
+ height: Math.abs(mousePos.y - startY)
2413
+ };
2414
+ const prevSelectedNodeIds = selectedNodeIds;
2415
+ const prevSelectedEdgeIds = selectedEdgeIds;
2416
+ selectedNodeIds = new Set(
2417
+ getNodesInside3(
2418
+ nodeLookup,
2419
+ nextUserSelectRect,
2420
+ store.transform,
2421
+ store.selectionMode === SelectionMode.Partial,
2422
+ true
2423
+ ).map((n) => n.id)
2424
+ );
2425
+ const edgesSelectable = store.defaultEdgeOptions.selectable ?? true;
2426
+ selectedEdgeIds = /* @__PURE__ */ new Set();
2427
+ for (const nodeId of selectedNodeIds) {
2428
+ const connections = connectionLookup.get(nodeId);
2429
+ if (!connections) continue;
2430
+ for (const { edgeId } of connections.values()) {
2431
+ const edge = edgeLookup.get(edgeId);
2432
+ if (edge && (edge.selectable ?? edgesSelectable)) {
2433
+ selectedEdgeIds.add(edgeId);
2434
+ }
2435
+ }
2436
+ }
2437
+ batch3(() => {
2438
+ if (!isSetEqual(prevSelectedNodeIds, selectedNodeIds)) {
2439
+ const selectionMap = /* @__PURE__ */ new Map();
2440
+ actions.setNodes(
2441
+ (node) => {
2442
+ const isSelected = selectedNodeIds.has(node.id);
2443
+ selectionMap.set(node.id, isSelected);
2444
+ return !!node.selected !== isSelected;
2445
+ },
2446
+ produce2((node) => {
2447
+ node.selected = selectionMap.get(node.id);
2448
+ })
2449
+ );
2450
+ }
2451
+ if (!isSetEqual(prevSelectedEdgeIds, selectedEdgeIds)) {
2452
+ const selectionMap = /* @__PURE__ */ new Map();
2453
+ actions.setEdges(
2454
+ (edge) => {
2455
+ const isSelected = selectedEdgeIds.has(edge.id);
2456
+ selectionMap.set(edge.id, isSelected);
2457
+ return !!edge.selected !== isSelected;
2458
+ },
2459
+ produce2((edge) => {
2460
+ edge.selected = selectionMap.get(edge.id);
2461
+ })
2462
+ );
2463
+ }
2464
+ actions.setSelectionRectMode("user");
2465
+ actions.setSelectionRect(nextUserSelectRect);
2466
+ });
2467
+ };
2468
+ const onPointerUp = (event) => {
2469
+ if (event.button !== 0) return;
2470
+ event.target?.releasePointerCapture?.(event.pointerId);
2471
+ if (!isSelecting() && store.selectionRectMode === "user" && event.target === container) {
2472
+ onClick(event);
2473
+ }
2474
+ batch3(() => {
2475
+ actions.setSelectionRect(void 0);
2476
+ if (selectedNodeIds.size > 0) {
2477
+ actions.setSelectionRectMode("nodes");
2478
+ }
2479
+ });
2480
+ if (store.selectionKeyPressed) {
2481
+ selectionInProgress = false;
2482
+ }
2483
+ props.onSelectionEnd?.(event);
2484
+ };
2485
+ const onContextMenu = (event) => {
2486
+ if (event.target !== container) return;
2487
+ const result = _panOnDrag();
2488
+ if (Array.isArray(result) && result.includes(2)) {
2489
+ event.preventDefault();
2490
+ return;
2491
+ }
2492
+ props.onPaneContextMenu?.({ event });
2493
+ };
2494
+ return <div
2495
+ ref={container}
2496
+ class={clsx7("solid-flow__container solid-flow__pane", {
2497
+ selection: isSelecting(),
2498
+ dragging: store.dragging,
2499
+ draggable: props.panOnDrag === true || Array.isArray(props.panOnDrag) && props.panOnDrag.includes(0)
2500
+ })}
2501
+ onClick={(e) => hasActiveSelection() ? void 0 : onClick(e)}
2502
+ onPointerDown={(e) => hasActiveSelection() ? onPointerDown(e) : void 0}
2503
+ onPointerMove={(e) => hasActiveSelection() ? onPointerMove(e) : void 0}
2504
+ onPointerUp={(e) => hasActiveSelection() ? onPointerUp(e) : void 0}
2505
+ onContextMenu={onContextMenu}
2506
+ >
2507
+ {props.children}
2508
+ </div>;
2509
+ };
2510
+
2511
+ // src/components/container/Panel.tsx
2512
+ import clsx8 from "clsx";
2513
+ import { mergeProps as mergeProps10, splitProps as splitProps5 } from "solid-js";
2514
+ var Panel = (props) => {
2515
+ const { store } = useInternalSolidFlow();
2516
+ const _props = mergeProps10(
2517
+ {
2518
+ position: "top-right",
2519
+ style: {}
2520
+ },
2521
+ props
2522
+ );
2523
+ const [local, rest] = splitProps5(_props, ["class", "position", "style", "children"]);
2524
+ return <div
2525
+ class={clsx8(["solid-flow__panel", ...local.position.split("-"), local.class])}
2526
+ style={{
2527
+ "pointer-events": store.selectionRectMode ? "none" : void 0,
2528
+ ...local.style
2529
+ }}
2530
+ {...rest}
2531
+ >
2532
+ {local.children}
2533
+ </div>;
2534
+ };
2535
+
2536
+ // src/components/container/Viewport.tsx
2537
+ var Viewport = (props) => {
2538
+ const { store } = useInternalSolidFlow();
2539
+ return <div
2540
+ class="solid-flow__container solid-flow__viewport xyflow__viewport"
2541
+ style={{
2542
+ transform: `translate(${store.viewport.x}px, ${store.viewport.y}px) scale(${store.viewport.zoom})`
2543
+ }}
2544
+ >
2545
+ {props.children}
2546
+ </div>;
2547
+ };
2548
+
2549
+ // src/components/container/ViewportPortal.tsx
2550
+ import { Show as Show9 } from "solid-js";
2551
+ import { Portal as Portal2 } from "solid-js/web";
2552
+ var ViewportPortal = (props) => {
2553
+ const { store } = useInternalSolidFlow();
2554
+ return <Show9 when={store.domNode}>
2555
+ {(domNode) => <Portal2 mount={domNode().querySelector(".solid-flow__viewport-portal") ?? void 0}>
2556
+ {props.children}
2557
+ </Portal2>}
2558
+ </Show9>;
2559
+ };
2560
+
2561
+ // src/components/container/Zoom.tsx
2562
+ import {
2563
+ XYPanZoom
2564
+ } from "@xyflow/system";
2565
+ import { batch as batch4, createEffect as createEffect5, onMount as onMount2 } from "solid-js";
2566
+ var Zoom = (props) => {
2567
+ let ref;
2568
+ const { store, actions } = useInternalSolidFlow();
2569
+ const viewPort = () => props.initialViewport || { x: 0, y: 0, zoom: 1 };
2570
+ const panOnDrag = () => store.panActivationKeyPressed || props.panOnDrag;
2571
+ const panOnScroll = () => store.panActivationKeyPressed || props.panOnScroll;
2572
+ const onTransformChange = (transform) => {
2573
+ const [x, y, zoom] = transform;
2574
+ actions.setViewport({ x, y, zoom });
2575
+ };
2576
+ onMount2(() => {
2577
+ const panZoomInstance = XYPanZoom({
2578
+ domNode: ref,
2579
+ minZoom: store.minZoom,
2580
+ maxZoom: store.maxZoom,
2581
+ translateExtent: store.translateExtent,
2582
+ viewport: viewPort(),
2583
+ paneClickDistance: props.paneClickDistance,
2584
+ onDraggingChange: actions.setDragging,
2585
+ onPanZoomStart: props.onMoveStart,
2586
+ onPanZoom: props.onMove,
2587
+ onPanZoomEnd: props.onMoveEnd
2588
+ });
2589
+ const vp = panZoomInstance.getViewport();
2590
+ if (viewPort().x !== vp.x || viewPort().y !== vp.y || viewPort().zoom !== vp.zoom) {
2591
+ onTransformChange([vp.x, vp.y, vp.zoom]);
2592
+ }
2593
+ batch4(() => {
2594
+ actions.setViewport(vp);
2595
+ actions.setPanZoom(panZoomInstance);
2596
+ });
2597
+ props.onViewportInitialized?.();
2598
+ createEffect5(() => {
2599
+ panZoomInstance.update({
2600
+ lib: store.lib,
2601
+ zoomActivationKeyPressed: store.zoomActivationKeyPressed,
2602
+ noPanClassName: store.noPanClass,
2603
+ noWheelClassName: store.noWheelClass,
2604
+ userSelectionActive: !!store.selectionRect,
2605
+ panOnScrollSpeed: 0.5,
2606
+ panOnDrag: panOnDrag(),
2607
+ panOnScroll: panOnScroll(),
2608
+ zoomOnScroll: props.zoomOnScroll,
2609
+ zoomOnDoubleClick: props.zoomOnDoubleClick,
2610
+ zoomOnPinch: props.zoomOnPinch,
2611
+ panOnScrollMode: props.panOnScrollMode,
2612
+ preventScrolling: typeof props.preventScrolling === "boolean" ? props.preventScrolling : true,
2613
+ onTransformChange
2614
+ });
2615
+ });
2616
+ });
2617
+ return <div ref={ref} class="solid-flow__container solid-flow__zoom">
2618
+ {props.children}
2619
+ </div>;
2620
+ };
2621
+
2622
+ // src/components/graph/connection/ConnectionLine.tsx
2623
+ import {
2624
+ getBezierPath as getBezierPath3,
2625
+ getConnectionStatus,
2626
+ getSmoothStepPath as getSmoothStepPath5,
2627
+ getStraightPath as getStraightPath3
2628
+ } from "@xyflow/system";
2629
+ import clsx9 from "clsx";
2630
+ import { Show as Show10 } from "solid-js";
2631
+ var ConnectionLine = (props) => {
2632
+ const { store } = useInternalSolidFlow();
2633
+ const connectionStatus = () => getConnectionStatus(store.connection.isValid);
2634
+ return <Show10 when={store.connection.inProgress}>
2635
+ <svg
2636
+ class="solid-flow__container solid-flow__connectionline"
2637
+ width={store.width}
2638
+ height={store.height}
2639
+ style={props.containerStyle}
2640
+ >
2641
+ <g class={clsx9(["solid-flow__connection", connectionStatus()])}>
2642
+ <Show10 when={props.component} fallback={<InternalConnectionLine style={props.style} />}>
2643
+ {(CustomComponent) => {
2644
+ const UserConnectionLine = CustomComponent();
2645
+ return <UserConnectionLine
2646
+ connectionLineType={store.connectionLineType}
2647
+ connectionLineStyle={props.style}
2648
+ fromNode={store.connection.fromNode}
2649
+ fromHandle={store.connection.fromHandle}
2650
+ fromX={store.connection.from.x}
2651
+ fromY={store.connection.from.y}
2652
+ toX={store.connection.to.x}
2653
+ toY={store.connection.to.y}
2654
+ fromPosition={store.connection.fromPosition}
2655
+ toPosition={store.connection.toPosition}
2656
+ connectionStatus={connectionStatus()}
2657
+ toNode={store.connection.toNode}
2658
+ toHandle={store.connection.toHandle}
2659
+ />;
2660
+ }}
2661
+ </Show10>
100
2662
  </g>
101
2663
  </svg>
102
- </Sn>},Js=e=>{let{store:o}=z(),t=()=>{if(!o.connection.inProgress)return;let N={sourceX:o.connection.from.x,sourceY:o.connection.from.y,sourcePosition:o.connection.fromPosition,targetX:o.connection.to.x,targetY:o.connection.to.y,targetPosition:o.connection.toPosition};switch(o.connectionLineType){case"default":{let[S]=Fs(N);return S}case"straight":{let[S]=Zs(N);return S}case"step":case"smoothstep":{let[S]=Ws({...N,borderRadius:o.connectionLineType==="step"?0:void 0});return S}}};return<path class="solid-flow__connection-path"fill="none"style={e.style}d={t()}/>},St=Us;import ed from"clsx";import{mergeProps as od,Show as Sd}from"solid-js";import Gs from"clsx";import{mergeProps as js}from"solid-js";var Nn=e=>{let o=js({radius:5},e);return<circle class={Gs("solid-flow__background-pattern","dots",o.class)}cx={o.radius}cy={o.radius}r={o.radius}/>};import{clsx as qs}from"clsx";import{mergeProps as Qs}from"solid-js";var Pn=e=>{let o=Qs({lineWidth:1},e);return<path stroke-width={o.lineWidth}d={`M${o.dimensions[0]/2} 0 V${o.dimensions[1]} M0 ${o.dimensions[1]/2} H${o.dimensions[0]}`}class={qs("solid-flow__background-pattern",o.variant,o.class)}/>};var Nd={dots:1,lines:1,cross:6},Pd=e=>{let o=od({variant:"dots",gap:20,size:1,lineWidth:1,style:{}},e),{store:t}=z(),N=()=>o.variant==="dots",S=()=>o.variant==="cross",P=()=>`background-pattern-${t.id}-${o.id??""}`,x=()=>(o.size??Nd[o.variant])*t.viewport.zoom,b=()=>Array.isArray(o.gap)?o.gap:[o.gap,o.gap],C=()=>[b()[0]*t.viewport.zoom||1,b()[1]*t.viewport.zoom||1],T=()=>S()?[x(),x()]:C(),v=()=>N()?[x()/2,x()/2]:[T()[0]/2,T()[1]/2];return<svg data-testid="solid-flow__background"class={ed("solid-flow__container solid-flow__background",o.class)}style={{"--xy-background-color-props":o.bgColor,"--xy-background-pattern-color-props":o.patternColor,...o.style}}>
103
- <pattern id={P()}x={t.viewport.x%C()[0]}y={t.viewport.y%C()[1]}width={C()[0]}height={C()[1]}patternUnits="userSpaceOnUse"patternTransform={`translate(-${v()[0]},-${v()[1]})`}>
104
- <Sd when={!N()}fallback={<Nn radius={x()/2}class={o.patternClass}/>}>
105
- <Pn class={o.patternClass}dimensions={T()}variant={o.variant}lineWidth={o.lineWidth}/>
106
- </Sd>
2664
+ </Show10>;
2665
+ };
2666
+ var InternalConnectionLine = (props) => {
2667
+ const { store } = useInternalSolidFlow();
2668
+ const path = () => {
2669
+ if (!store.connection.inProgress) return void 0;
2670
+ const pathParams = {
2671
+ sourceX: store.connection.from.x,
2672
+ sourceY: store.connection.from.y,
2673
+ sourcePosition: store.connection.fromPosition,
2674
+ targetX: store.connection.to.x,
2675
+ targetY: store.connection.to.y,
2676
+ targetPosition: store.connection.toPosition
2677
+ };
2678
+ switch (store.connectionLineType) {
2679
+ case "default": {
2680
+ const [path2] = getBezierPath3(pathParams);
2681
+ return path2;
2682
+ }
2683
+ case "straight": {
2684
+ const [path2] = getStraightPath3(pathParams);
2685
+ return path2;
2686
+ }
2687
+ case "step":
2688
+ case "smoothstep": {
2689
+ const [path2] = getSmoothStepPath5({
2690
+ ...pathParams,
2691
+ borderRadius: store.connectionLineType === "step" ? 0 : void 0
2692
+ });
2693
+ return path2;
2694
+ }
2695
+ }
2696
+ };
2697
+ return <path class="solid-flow__connection-path" fill="none" style={props.style} d={path()} />;
2698
+ };
2699
+ var ConnectionLine_default = ConnectionLine;
2700
+
2701
+ // src/components/graph/plugins/background/Background.tsx
2702
+ import clsx12 from "clsx";
2703
+ import { mergeProps as mergeProps13, Show as Show11 } from "solid-js";
2704
+
2705
+ // src/components/graph/plugins/background/DotPattern.tsx
2706
+ import clsx10 from "clsx";
2707
+ import { mergeProps as mergeProps11 } from "solid-js";
2708
+ var DotPattern = (props) => {
2709
+ const _props = mergeProps11({ radius: 5 }, props);
2710
+ return <circle
2711
+ class={clsx10("solid-flow__background-pattern", "dots", _props.class)}
2712
+ cx={_props.radius}
2713
+ cy={_props.radius}
2714
+ r={_props.radius}
2715
+ />;
2716
+ };
2717
+
2718
+ // src/components/graph/plugins/background/LinePattern.tsx
2719
+ import { clsx as clsx11 } from "clsx";
2720
+ import { mergeProps as mergeProps12 } from "solid-js";
2721
+ var LinePattern = (props) => {
2722
+ const _props = mergeProps12({ lineWidth: 1 }, props);
2723
+ return <path
2724
+ stroke-width={_props.lineWidth}
2725
+ d={`M${_props.dimensions[0] / 2} 0 V${_props.dimensions[1]} M0 ${_props.dimensions[1] / 2} H${_props.dimensions[0]}`}
2726
+ class={clsx11("solid-flow__background-pattern", _props.variant, _props.class)}
2727
+ />;
2728
+ };
2729
+
2730
+ // src/components/graph/plugins/background/Background.tsx
2731
+ var DEFAULT_SIZE = {
2732
+ dots: 1,
2733
+ lines: 1,
2734
+ cross: 6
2735
+ };
2736
+ var Background = (props) => {
2737
+ const _props = mergeProps13(
2738
+ {
2739
+ variant: "dots",
2740
+ gap: 20,
2741
+ size: 1,
2742
+ lineWidth: 1,
2743
+ style: {}
2744
+ },
2745
+ props
2746
+ );
2747
+ const { store } = useInternalSolidFlow();
2748
+ const isDots = () => _props.variant === "dots";
2749
+ const isCross = () => _props.variant === "cross";
2750
+ const patternId = () => `background-pattern-${store.id}-${_props.id ?? ""}`;
2751
+ const scaledSize = () => (_props.size ?? DEFAULT_SIZE[_props.variant]) * store.viewport.zoom;
2752
+ const gapXY = () => Array.isArray(_props.gap) ? _props.gap : [_props.gap, _props.gap];
2753
+ const scaledGap = () => [gapXY()[0] * store.viewport.zoom || 1, gapXY()[1] * store.viewport.zoom || 1];
2754
+ const patternDimensions = () => isCross() ? [scaledSize(), scaledSize()] : scaledGap();
2755
+ const patternOffset = () => isDots() ? [scaledSize() / 2, scaledSize() / 2] : [patternDimensions()[0] / 2, patternDimensions()[1] / 2];
2756
+ return <svg
2757
+ data-testid="solid-flow__background"
2758
+ class={clsx12("solid-flow__container solid-flow__background", _props.class)}
2759
+ style={{
2760
+ "--xy-background-color-props": _props.bgColor,
2761
+ "--xy-background-pattern-color-props": _props.patternColor,
2762
+ ..._props.style
2763
+ }}
2764
+ >
2765
+ <pattern
2766
+ id={patternId()}
2767
+ x={store.viewport.x % scaledGap()[0]}
2768
+ y={store.viewport.y % scaledGap()[1]}
2769
+ width={scaledGap()[0]}
2770
+ height={scaledGap()[1]}
2771
+ patternUnits="userSpaceOnUse"
2772
+ patternTransform={`translate(-${patternOffset()[0]},-${patternOffset()[1]})`}
2773
+ >
2774
+ <Show11
2775
+ when={!isDots()}
2776
+ fallback={<DotPattern radius={scaledSize() / 2} class={_props.patternClass} />}
2777
+ >
2778
+ <LinePattern
2779
+ class={_props.patternClass}
2780
+ dimensions={patternDimensions()}
2781
+ variant={_props.variant}
2782
+ lineWidth={_props.lineWidth}
2783
+ />
2784
+ </Show11>
107
2785
  </pattern>
108
- <rect x="0"y="0"width="100%"height="100%"fill={`url(#${P()})`}/>
109
- </svg>};import bd from"clsx";import{splitProps as Ed}from"solid-js";var Me=e=>{let[o,t]=Ed(e,["class","bgColor","bgColorHover","color","colorHover","borderColor","onClick","children"]),N=()=>Object.entries({"--xy-controls-button-background-color-props":o.bgColor,"--xy-controls-button-background-color-hover-props":o.bgColorHover,"--xy-controls-button-color-props":o.color,"--xy-controls-button-color-hover-props":o.colorHover,"--xy-controls-button-border-color-props":o.borderColor}).filter(([S,P])=>P!==void 0).reduce((S,[P,x])=>(S[P]=x,S),{});return<button type="button"class={bd("solid-flow__controls-button",o.class)}onClick={S=>o.onClick?.(S)}style={N()}{...t}>
110
- {o.children}
111
- </button>};import xd from"clsx";import{batch as wd,mergeProps as Cd,Show as Qe,splitProps as Td}from"solid-js";var Nt=()=><svg xmlns="http://www.w3.org/2000/svg"viewBox="0 0 32 30">
112
- <path d="M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z"/>
113
- </svg>;var Pt=()=><svg xmlns="http://www.w3.org/2000/svg"viewBox="0 0 25 32">
114
- <path d="M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z"/>
115
- </svg>;var Et=()=><svg xmlns="http://www.w3.org/2000/svg"viewBox="0 0 32 5">
116
- <path d="M0 0h32v4.2H0z"/>
117
- </svg>;var Ct=()=><svg xmlns="http://www.w3.org/2000/svg"viewBox="0 0 32 32">
118
- <path d="M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"/>
119
- </svg>;var Tt=()=><svg xmlns="http://www.w3.org/2000/svg"viewBox="0 0 25 32">
120
- <path d="M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z"/>
121
- </svg>;var vd=e=>{let{store:o,actions:t}=z(),N=Cd({position:"bottom-left",showZoom:!0,showFitView:!0,showLock:!0,orientation:"vertical"},e),[S,P]=Td(N,["class","position","showZoom","showFitView","showLock","orientation","fitViewOptions","beforeControls","afterControls","buttonBgColor","buttonBgColorHover","buttonColor","buttonColorHover","buttonBorderColor","style","children"]),x=()=>o.viewport.zoom<=o.minZoom,b=()=>o.viewport.zoom>=o.maxZoom,C=()=>o.nodesDraggable||o.nodesConnectable||o.elementsSelectable,T=()=>{t.zoomIn()},v=()=>{t.zoomOut()},E=()=>{t.fitView(S.fitViewOptions)},w=()=>{let D=!C();wd(()=>{t.setNodesDraggable(D),t.setNodesConnectable(D),t.setElementsSelectable(D)})},I=()=>({bgColor:S.buttonBgColor,bgColorHover:S.buttonBgColorHover,color:S.buttonColor,colorHover:S.buttonColorHover,borderColor:S.buttonBorderColor});return<Pe class={xd(["solid-flow__controls",S.orientation,S.class])}position={S.position}data-testid="solid-flow__controls"aria-label={o.ariaLabelConfig["controls.ariaLabel"]}style={S.style}{...P}>
122
- {S.beforeControls}
123
- <Qe when={S.showZoom}>
2786
+ <rect x="0" y="0" width="100%" height="100%" fill={`url(#${patternId()})`} />
2787
+ </svg>;
2788
+ };
2789
+
2790
+ // src/components/graph/plugins/controls/ControlButton.tsx
2791
+ import clsx13 from "clsx";
2792
+ import { splitProps as splitProps6 } from "solid-js";
2793
+ var ControlButton = (props) => {
2794
+ const [local, rest] = splitProps6(props, [
2795
+ "class",
2796
+ "bgColor",
2797
+ "bgColorHover",
2798
+ "color",
2799
+ "colorHover",
2800
+ "borderColor",
2801
+ "onClick",
2802
+ "children"
2803
+ ]);
2804
+ const style = () => Object.entries({
2805
+ "--xy-controls-button-background-color-props": local.bgColor,
2806
+ "--xy-controls-button-background-color-hover-props": local.bgColorHover,
2807
+ "--xy-controls-button-color-props": local.color,
2808
+ "--xy-controls-button-color-hover-props": local.colorHover,
2809
+ "--xy-controls-button-border-color-props": local.borderColor
2810
+ }).filter(([_, value]) => value !== void 0).reduce((acc, [key, value]) => {
2811
+ acc[key] = value;
2812
+ return acc;
2813
+ }, {});
2814
+ return <button
2815
+ type="button"
2816
+ class={clsx13("solid-flow__controls-button", local.class)}
2817
+ onClick={(e) => local.onClick?.(e)}
2818
+ style={style()}
2819
+ {...rest}
2820
+ >
2821
+ {local.children}
2822
+ </button>;
2823
+ };
2824
+
2825
+ // src/components/graph/plugins/controls/Controls.tsx
2826
+ import clsx14 from "clsx";
2827
+ import { batch as batch5, mergeProps as mergeProps14, Show as Show12, splitProps as splitProps7 } from "solid-js";
2828
+
2829
+ // src/components/graph/plugins/controls/icons/Fit.tsx
2830
+ var Fit = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 30">
2831
+ <path d="M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z" />
2832
+ </svg>;
2833
+
2834
+ // src/components/graph/plugins/controls/icons/Lock.tsx
2835
+ var Lock = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 32">
2836
+ <path d="M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z" />
2837
+ </svg>;
2838
+
2839
+ // src/components/graph/plugins/controls/icons/Minus.tsx
2840
+ var Minus = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 5">
2841
+ <path d="M0 0h32v4.2H0z" />
2842
+ </svg>;
2843
+
2844
+ // src/components/graph/plugins/controls/icons/Plus.tsx
2845
+ var Plus = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
2846
+ <path d="M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z" />
2847
+ </svg>;
2848
+
2849
+ // src/components/graph/plugins/controls/icons/Unlock.tsx
2850
+ var Unlock = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 32">
2851
+ <path d="M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z" />
2852
+ </svg>;
2853
+
2854
+ // src/components/graph/plugins/controls/Controls.tsx
2855
+ var Controls = (props) => {
2856
+ const { store, actions } = useInternalSolidFlow();
2857
+ const _props = mergeProps14(
2858
+ {
2859
+ position: "bottom-left",
2860
+ showZoom: true,
2861
+ showFitView: true,
2862
+ showLock: true,
2863
+ orientation: "vertical"
2864
+ },
2865
+ props
2866
+ );
2867
+ const [local, rest] = splitProps7(_props, [
2868
+ "class",
2869
+ "position",
2870
+ "showZoom",
2871
+ "showFitView",
2872
+ "showLock",
2873
+ "orientation",
2874
+ "fitViewOptions",
2875
+ "beforeControls",
2876
+ "afterControls",
2877
+ "buttonBgColor",
2878
+ "buttonBgColorHover",
2879
+ "buttonColor",
2880
+ "buttonColorHover",
2881
+ "buttonBorderColor",
2882
+ "style",
2883
+ "children"
2884
+ ]);
2885
+ const getMinZoomReached = () => store.viewport.zoom <= store.minZoom;
2886
+ const getMaxZoomReached = () => store.viewport.zoom >= store.maxZoom;
2887
+ const getIsInteractive = () => store.nodesDraggable || store.nodesConnectable || store.elementsSelectable;
2888
+ const onZoomInHandler = () => {
2889
+ void actions.zoomIn();
2890
+ };
2891
+ const onZoomOutHandler = () => {
2892
+ void actions.zoomOut();
2893
+ };
2894
+ const onFitViewHandler = () => {
2895
+ void actions.fitView(local.fitViewOptions);
2896
+ };
2897
+ const onToggleInteractivity = () => {
2898
+ const newValue = !getIsInteractive();
2899
+ batch5(() => {
2900
+ actions.setNodesDraggable(newValue);
2901
+ actions.setNodesConnectable(newValue);
2902
+ actions.setElementsSelectable(newValue);
2903
+ });
2904
+ };
2905
+ const buttonProps = () => ({
2906
+ bgColor: local.buttonBgColor,
2907
+ bgColorHover: local.buttonBgColorHover,
2908
+ color: local.buttonColor,
2909
+ colorHover: local.buttonColorHover,
2910
+ borderColor: local.buttonBorderColor
2911
+ });
2912
+ return <Panel
2913
+ class={clsx14(["solid-flow__controls", local.orientation, local.class])}
2914
+ position={local.position}
2915
+ data-testid="solid-flow__controls"
2916
+ aria-label={store.ariaLabelConfig["controls.ariaLabel"]}
2917
+ style={local.style}
2918
+ {...rest}
2919
+ >
2920
+ {local.beforeControls}
2921
+ <Show12 when={local.showZoom}>
124
2922
  <>
125
- <Me onClick={T}class="solid-flow__controls-zoomin"title={o.ariaLabelConfig["controls.zoomIn.ariaLabel"]}aria-label={o.ariaLabelConfig["controls.zoomIn.ariaLabel"]}disabled={b()}{...I()}>
126
- <Ct/>
127
- </Me>
128
- <Me onClick={v}class="solid-flow__controls-zoomout"title={o.ariaLabelConfig["controls.zoomOut.ariaLabel"]}aria-label={o.ariaLabelConfig["controls.zoomOut.ariaLabel"]}disabled={x()}{...I()}>
129
- <Et/>
130
- </Me>
2923
+ <ControlButton
2924
+ onClick={onZoomInHandler}
2925
+ class="solid-flow__controls-zoomin"
2926
+ title={store.ariaLabelConfig["controls.zoomIn.ariaLabel"]}
2927
+ aria-label={store.ariaLabelConfig["controls.zoomIn.ariaLabel"]}
2928
+ disabled={getMaxZoomReached()}
2929
+ {...buttonProps()}
2930
+ >
2931
+ <Plus />
2932
+ </ControlButton>
2933
+ <ControlButton
2934
+ onClick={onZoomOutHandler}
2935
+ class="solid-flow__controls-zoomout"
2936
+ title={store.ariaLabelConfig["controls.zoomOut.ariaLabel"]}
2937
+ aria-label={store.ariaLabelConfig["controls.zoomOut.ariaLabel"]}
2938
+ disabled={getMinZoomReached()}
2939
+ {...buttonProps()}
2940
+ >
2941
+ <Minus />
2942
+ </ControlButton>
131
2943
  </>
132
- </Qe>
133
- <Qe when={S.showFitView}>
134
- <Me class="solid-flow__controls-fitview"onClick={E}title={o.ariaLabelConfig["controls.fitView.ariaLabel"]}aria-label={o.ariaLabelConfig["controls.fitView.ariaLabel"]}{...I()}>
135
- <Nt/>
136
- </Me>
137
- </Qe>
138
- <Qe when={S.showLock}>
139
- <Me class="solid-flow__controls-interactive"onClick={w}title={o.ariaLabelConfig["controls.interactive.ariaLabel"]}aria-label={o.ariaLabelConfig["controls.interactive.ariaLabel"]}{...I()}>
140
- <Qe when={C()}fallback={<Pt/>}>
141
- <Tt/>
142
- </Qe>
143
- </Me>
144
- </Qe>
145
- {S.children}
146
- {S.afterControls}
147
- </Pe>};import{getBoundsOfRects as kd,getInternalNodesBounds as Dd,getNodeDimensions as Od,nodeHasDimensions as zd,XYMinimap as Rd}from"@xyflow/system";import Ad from"clsx";import{createEffect as _d,createMemo as xn,createSignal as Ld,Index as Hd,mergeProps as Bd,onCleanup as Vd,onMount as Kd,Show as Cn,splitProps as Xd}from"solid-js";import Md from"clsx";import{mergeProps as Id}from"solid-js";var En=e=>{let o=Id({borderRadius:5,width:0,height:0},e),t=()=>Object.entries({fill:o.color,stroke:o.strokeColor,"stroke-width":o.strokeWidth}).filter(([N,S])=>S!==void 0).reduce((N,[S,P])=>(N[S]=P,N),{});return<rect class={Md("solid-flow__minimap-node",{selected:o.selected},o.class)}x={o.x}y={o.y}rx={o.borderRadius}ry={o.borderRadius}width={o.width}height={o.height}shape-rendering={o.shapeRendering}style={t()}/>};var vt=e=>e instanceof Function?e:()=>e,Fd=e=>{let{store:o,nodeLookup:t}=z(),N=Bd({position:"bottom-right",nodeClass:"",nodeStrokeColor:"transparent",pannable:!0,zoomable:!0,width:200,height:150,nodeBorderRadius:5,nodeStrokeWidth:2,style:{}},e),[S,P]=Xd(N,["class","style","position","nodeClass","nodeStrokeColor","nodeColor","pannable","zoomable","inversePan","zoomStep","bgColor","width","height","maskColor","maskStrokeColor","maskStrokeWidth","nodeBorderRadius","nodeStrokeWidth"]),x=()=>S.nodeColor===void 0?void 0:vt(S.nodeColor),b=()=>vt(S.nodeStrokeColor),C=()=>vt(S.nodeClass),T=()=>typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision",v=xn(()=>`solid-flow__minimap-desc-${o.id}`),E=()=>({x:-o.viewport.x/o.viewport.zoom,y:-o.viewport.y/o.viewport.zoom,width:o.width/o.viewport.zoom,height:o.height/o.viewport.zoom}),w=()=>{let O=E();return t.size>0?kd(Dd(t),O):O},I=()=>w().width/S.width,D=()=>w().height/S.height,k=()=>Math.max(I(),D()),R=()=>k()*S.width,Y=()=>k()*S.height,H=()=>5*k(),_=()=>{let O=w();return O.x-(R()-O.width)/2-H()},$=()=>{let O=w();return O.y-(Y()-O.height)/2-H()},ee=()=>R()+H()*2,ie=()=>Y()+H()*2,de=()=>S.maskStrokeWidth?S.maskStrokeWidth*k():void 0,U=[],G=()=>{let O=o.nodes.map(K=>K.id),F=new Set(O);return(U.length!==O.length||!U.every(K=>F.has(K)))&&(U=O),U};return<Pe position={S.position}data-testid="solid-flow__minimap"class={Ad(["solid-flow__minimap",S.class])}style={{"--xy-minimap-background-color-props":S.bgColor,...S.style}}{...P}>
148
- <Cn when={o.panZoom}>
149
- {O=>{let[F,K]=Ld();return Kd(()=>{let Z=Rd({domNode:F(),panZoom:O(),getTransform:()=>o.transform,getViewScale:k});_d(()=>{Z.update({translateExtent:o.translateExtent,width:o.width,height:o.height,inversePan:S.inversePan,zoomStep:S.zoomStep,pannable:S.pannable,zoomable:S.zoomable})}),Vd(()=>{Z.destroy()})}),<svg ref={K}width={S.width}height={S.height}viewBox={`${_()} ${$()} ${ee()} ${ie()}`}class="solid-flow__minimap-svg"role="img"aria-labelledby={v()}style={{"--xy-minimap-mask-background-color-props":S.maskColor,"--xy-minimap-mask-stroke-color-props":S.maskStrokeColor,"--xy-minimap-mask-stroke-width-props":de()}}>
150
- <title id={v()}>{o.ariaLabelConfig["minimap.ariaLabel"]}</title>
151
- <Hd each={G()}>
152
- {Z=>{let te=xn(()=>t.get(Z())),Ot=()=>!!(te()&&zd(te())&&!te().hidden);return<Cn when={Ot()&&Od(te())}>
153
- {Le=><En x={te().internals.positionAbsolute.x}y={te().internals.positionAbsolute.y}borderRadius={S.nodeBorderRadius}strokeWidth={S.nodeStrokeWidth}shapeRendering={T()}width={Le().width}height={Le().height}selected={te().selected}color={x()?.call(null,te())}strokeColor={b().call(null,te())}class={C().call(null,te())}/>}
154
- </Cn>}}
155
- </Hd>
156
- <path class="solid-flow__minimap-mask"d={`M${_()-H()},${$()-H()}h${ee()+H()*2}v${ie()+H()*2}h${-ee()-H()*2}z
157
- M${E().x},${E().y}h${E().width}v${E().height}h${-E().width}z`}fill-rule="evenodd"pointer-events="none"/>
158
- </svg>}}
159
- </Cn>
160
- </Pe>};import{XY_RESIZER_HANDLE_POSITIONS as qd,XY_RESIZER_LINE_POSITIONS as Qd}from"@xyflow/system";import{For as Tn,mergeProps as ea,Show as Sa,splitProps as Na}from"solid-js";import{XYResizer as Yd}from"@xyflow/system";import Wd from"clsx";import{createEffect as Zd,mergeProps as $d,onCleanup as Ud,onMount as Jd,splitProps as Gd}from"solid-js";import{produce as jd}from"solid-js/store";var So=e=>{let o=$d({variant:"handle",minWidth:10,minHeight:10,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE,keepAspectRatio:!1,autoScale:!0,style:{}},e),[t,N]=Gd(o,["nodeId","variant","position","minWidth","minHeight","maxWidth","maxHeight","keepAspectRatio","autoScale","onResizeStart","onResize","onResizeEnd","shouldResize","class","children","color","style"]),S,{store:P,nodeLookup:x,actions:b}=z(),C=Oe(),T=()=>t.nodeId??C(),v=()=>t.variant==="line",E=()=>t.position??(v()?"right":"bottom-right"),w=()=>E().split("-");return Jd(()=>{let I=Yd({domNode:S,nodeId:T(),getStoreItems:()=>({nodeLookup:x,transform:P.transform,snapGrid:P.snapGrid,snapToGrid:!!P.snapGrid,nodeOrigin:P.nodeOrigin,paneDomNode:P.domNode}),onChange:(D,k)=>{let R=new Map,Y=D.x&&D.y?{x:D.x,y:D.y}:void 0;R.set(T(),{...D,position:Y});for(let H of k)R.set(H.id,{position:H.position});b.setNodes(H=>R.has(H.id),jd(H=>{let _=R.get(H.id);H.width=_.width,H.height=_.height,H.position={x:_.position?.x??H.position.x,y:_.position?.y??H.position.y}}))}});Zd(()=>{I.update({controlPosition:E(),boundaries:{minWidth:t.minWidth,minHeight:t.minHeight,maxWidth:t.maxWidth,maxHeight:t.maxHeight},keepAspectRatio:!!t.keepAspectRatio,onResizeStart:t.onResizeStart,onResize:t.onResize,onResizeEnd:t.onResizeEnd,shouldResize:t.shouldResize})}),Ud(()=>{I.destroy()})}),<div ref={S}class={Wd(["solid-flow__resize-control",t.variant,P.noDragClass,...w(),t.class])}style={{"border-color":v()?t.color:void 0,"background-color":v()?void 0:t.color,scale:v()||!t.autoScale?void 0:Math.max(1/P.viewport.zoom,1),...t.style}}{...N}>
161
- {t.children}
162
- </div>};var Pa=e=>{let o=ea({autoScale:!0,visible:!0},e),[t,N]=Na(e,["handleClass","handleStyle","lineClass","lineStyle"]);return<Sa when={o.visible}>
163
- <Tn each={Qd}>
164
- {S=><So variant="line"position={S}class={t.lineClass}style={t.lineStyle}{...N}/>}
165
- </Tn>
166
- <Tn each={qd}>
167
- {S=><So position={S}class={t.handleClass}style={t.handleStyle}{...N}/>}
168
- </Tn>
169
- </Sa>};import{getNodeToolbarTransform as Ha}from"@xyflow/system";import{mergeProps as Ba,Show as Va,splitProps as Ka,useContext as Xa}from"solid-js";import{Portal as Fa}from"solid-js/web";function Vu(){let{store:e}=z();return()=>e.connection}function ba(){let{store:e}=z();return()=>e.nodes}function Ea(){let{store:e}=z();return()=>e.edges}function xa(){let{store:e}=z();return()=>e.viewport}import"@xyflow/system";import{batch as wa}from"solid-js";function Uu(){let{store:e,edgeLookup:o,actions:t}=z();return N=>{let S=o.get(N);if(!S)return;(S.selectable||e.elementsSelectable&&typeof S.selectable>"u")&&wa(()=>{t.setSelectionRect(void 0),t.setSelectionRectMode(void 0),S.selected?S.selected&&e.multiselectionKeyPressed&&t.unselectNodesAndEdges({nodes:[],edges:[S]}):t.addSelectedEdges([N])})}}function ju(e){let{nodeLookup:o}=z();return()=>o.get(e())}import{areConnectionMapsEqual as Ca}from"@xyflow/system";import{createEffect as Ta,createSignal as va,useContext as Ma}from"solid-js";var ny=e=>{let{connectionLookup:o}=z(),t=()=>{let T=Ma(Ne);return T?T():""},N=()=>e().handleId,S=()=>e().handleType,P=()=>e().id??t(),[x,b]=va([]),C=()=>`${P()}${S()?N()?`-${S()}-${N()}`:`-${S()}`:""}`;return Ta(T=>{let v=o.get(C());return Ca(v,T)||(T=v,b(Array.from(T?.values()??[]))),v}),x};import{shallowNodeData as Ia}from"@xyflow/system";import{createMemo as ka}from"solid-js";function ay(e){let{nodeLookup:o}=z(),t=[];return ka(()=>{let S=[],P=e();if(!P)return;let x=Array.isArray(P)?P:[P];for(let b of x){let C=o.get(b)?.internals.userNode;C&&S.push({id:C.id,type:C.type,data:C.data})}return Ia(S,t)||(t=S),Array.isArray(P)?S:S[0]})}import{evaluateAbsolutePosition as Da,getElementsToRemove as Oa,getNodesBounds as za,getOverlappingArea as vn,getViewportForBounds as Ra,isRectObject as Mn,nodeToRect as In,pointToRendererPoint as Aa,rendererPointToPoint as _a}from"@xyflow/system";import{batch as La}from"solid-js";import{unwrap as No}from"solid-js/store";function Po(){let{store:e,actions:o,nodeLookup:t,edgeLookup:N,connectionLookup:S}=z(),P=E=>{let w=wo(E)?E:t.get(E.id),I=w.parentId?Da(w.position,w.measured,w.parentId,t,e.nodeOrigin):w.position,D={...w,position:I,width:w.measured?.width??w.width,height:w.measured?.height??w.height};return In(D)},x=(E,w,I={replace:!1})=>{o.setNodes(D=>D.id===E,D=>{let k=typeof w=="function"?w(D):w;return I?.replace&&wo(k)?k:{...D,...k}})},b=(E,w,I={replace:!1})=>{o.setEdges(D=>D.id===E,D=>{let k=typeof w=="function"?w(D):w;return I.replace&&$t(k)?k:{...D,...k}})},C=E=>t.get(E),T=E=>{let w=Array.isArray(E)?E:[E];o.setNodes(I=>[...I,...w])},v=E=>{let w=Array.isArray(E)?E:[E];o.setEdges(I=>[...I,...w])};return{zoomIn:o.zoomIn,zoomOut:o.zoomOut,getInternalNode:C,setCenter:o.setCenter,fitView:o.fitView,getNode:E=>C(E)?.internals.userNode,getNodes:E=>E?kn(t,E):e.nodes,getEdge:E=>N.get(E),getEdges:E=>E?kn(N,E):e.edges,addNodes:T,addEdges:v,getViewport:()=>No(e.viewport),setViewport:async(E,w)=>{let I=e.viewport;return e.panZoom?(await e.panZoom.setViewport({x:E.x??I.x,y:E.y??I.y,zoom:E.zoom??I.zoom},w),Promise.resolve(!0)):Promise.resolve(!1)},getZoom:()=>e.viewport.zoom,setZoom:(E,w)=>{let I=e.panZoom;return I?I.scaleTo(E,{duration:w?.duration}):Promise.resolve(!1)},fitBounds:async(E,w)=>{if(!e.panZoom)return Promise.resolve(!1);let I=Ra(E,e.width,e.height,e.minZoom,e.maxZoom,w?.padding??.1);return await e.panZoom.setViewport(I,{duration:w?.duration,ease:w?.ease,interpolate:w?.interpolate}),Promise.resolve(!0)},getIntersectingNodes:(E,w=!0,I)=>{let D=Mn(E),k=D?E:P(E);return k?(I||e.nodes).filter(R=>{let Y=t.get(R.id);if(!Y||!D&&R.id===E.id)return!1;let H=In(Y),_=vn(H,k);return w&&_>0||_>=k.width*k.height}):[]},isNodeIntersecting:(E,w,I=!0)=>{let k=Mn(E)?E:P(E);if(!k)return!1;let R=vn(k,w);return I&&R>0||R>=k.width*k.height},deleteElements:async({nodes:E=[],edges:w=[]})=>{let{nodes:I,edges:D}=await Oa({nodesToRemove:E,edgesToRemove:w,nodes:e.nodes,edges:e.edges,onBeforeDelete:e.onBeforeDelete});return La(()=>{if(D){let k=e.edges.filter(R=>!D.some(({id:Y})=>Y===R.id));e.onEdgesDelete?.(D),o.setEdges(k)}if(I){let k=e.nodes.filter(R=>!I.some(({id:Y})=>Y===R.id));e.onNodesDelete?.(I),o.setNodes(k)}}),{deletedNodes:I,deletedEdges:D}},screenToFlowPosition:(E,w={snapToGrid:!0})=>{if(!e.domNode)return E;let I=w.snapToGrid?e.snapGrid:!1,{x:D,y:k,zoom:R}=e.viewport,{x:Y,y:H}=e.domNode.getBoundingClientRect(),_={x:E.x-Y,y:E.y-H};return Aa(_,[D,k,R],I!==null,I||[1,1])},flowToScreenPosition:E=>{if(!e.domNode)return E;let{x:w,y:I,zoom:D}=e.viewport,{x:k,y:R}=e.domNode.getBoundingClientRect(),Y=_a(E,[w,I,D]);return{x:Y.x+k,y:Y.y+R}},toObject:()=>structuredClone({nodes:[...No(e.nodes)],edges:[...No(e.edges)],viewport:{...No(e.viewport)}}),updateNode:x,updateNodeData:(E,w,I)=>{let D=t.get(E)?.internals.userNode;if(!D)return;let k=typeof w=="function"?w(D):w;x(E,R=>({...R,data:I?.replace?k:{...R.data,...k}}))},updateEdge:b,getNodesBounds:E=>za(E,{nodeLookup:t,nodeOrigin:e.nodeOrigin}),getHandleConnections:({type:E,id:w,nodeId:I})=>Array.from(S.get(`${I}-${E}-${w??null}`)?.values()??[])}}function kn(e,o){let t=[];for(let N of o){let S=e.get(N);if(S){let P="internals"in S?S.internals?.userNode:S;t.push(P)}}return t}function hy(){let{store:e,actions:o}=z();return N=>{let S=Array.isArray(N)?N:[N],P=[];for(let x of S){let b=e.domNode?.querySelector(`.solid-flow__node[data-id="${x}"]`);b&&P.push([x,{id:x,nodeElement:b,force:!0}])}o.requestUpdateNodeInternals(P)}}var _y=e=>{let{store:o}=z(),{getNodes:t,getNodesBounds:N,getInternalNode:S}=Po(),P=Ba({offset:10,position:"top",align:"center",style:{}},e),[x,b]=Ka(P,["nodeId","position","align","offset","isVisible","style","children"]),C=()=>{let k=Xa(Ne);return k?k():""},T=()=>(Array.isArray(x.nodeId)?x.nodeId:[x.nodeId??C()]).reduce((R,Y)=>{let H=S(Y);return H&&R.push(H),R},[]),v=()=>{let k=N(T());return k?Ha(k,o.viewport,x.position,x.offset,x.align):""},E=()=>{let k=T();return k.length===0?1:Math.max(...k.map(R=>(R.internals.z||5)+1))},w=()=>t().filter(k=>k.selected).length,I=()=>{let k=T();return typeof x.isVisible=="boolean"?x.isVisible:k.length===1&&!!k[0].selected&&w()===1},D=()=>!!(o.domNode&&I()&&T().length>0);return<Va when={D()}>
170
- <Fa mount={o.domNode}>
171
- <div class="solid-flow__node-toolbar"data-id={T().reduce((k,R)=>`${k}${R.id} `,"").trim()}style={{position:"absolute",transform:v(),"z-index":E(),...x.style}}{...b}>
172
- {x.children}
2944
+ </Show12>
2945
+ <Show12 when={local.showFitView}>
2946
+ <ControlButton
2947
+ class="solid-flow__controls-fitview"
2948
+ onClick={onFitViewHandler}
2949
+ title={store.ariaLabelConfig["controls.fitView.ariaLabel"]}
2950
+ aria-label={store.ariaLabelConfig["controls.fitView.ariaLabel"]}
2951
+ {...buttonProps()}
2952
+ >
2953
+ <Fit />
2954
+ </ControlButton>
2955
+ </Show12>
2956
+ <Show12 when={local.showLock}>
2957
+ <ControlButton
2958
+ class="solid-flow__controls-interactive"
2959
+ onClick={onToggleInteractivity}
2960
+ title={store.ariaLabelConfig["controls.interactive.ariaLabel"]}
2961
+ aria-label={store.ariaLabelConfig["controls.interactive.ariaLabel"]}
2962
+ {...buttonProps()}
2963
+ >
2964
+ <Show12 when={getIsInteractive()} fallback={<Lock />}>
2965
+ <Unlock />
2966
+ </Show12>
2967
+ </ControlButton>
2968
+ </Show12>
2969
+ {local.children}
2970
+ {local.afterControls}
2971
+ </Panel>;
2972
+ };
2973
+
2974
+ // src/components/graph/plugins/minimap/MiniMap.tsx
2975
+ import {
2976
+ getBoundsOfRects as getBoundsOfRects2,
2977
+ getInternalNodesBounds as getInternalNodesBounds2,
2978
+ getNodeDimensions as getNodeDimensions3,
2979
+ nodeHasDimensions as nodeHasDimensions2,
2980
+ XYMinimap
2981
+ } from "@xyflow/system";
2982
+ import clsx16 from "clsx";
2983
+ import {
2984
+ createEffect as createEffect6,
2985
+ createMemo as createMemo7,
2986
+ createSignal as createSignal6,
2987
+ Index,
2988
+ mergeProps as mergeProps16,
2989
+ onCleanup as onCleanup4,
2990
+ onMount as onMount3,
2991
+ Show as Show13,
2992
+ splitProps as splitProps8
2993
+ } from "solid-js";
2994
+
2995
+ // src/components/graph/plugins/minimap/MiniMapNode.tsx
2996
+ import clsx15 from "clsx";
2997
+ import { mergeProps as mergeProps15 } from "solid-js";
2998
+ var MiniMapNode = (props) => {
2999
+ const _props = mergeProps15(
3000
+ {
3001
+ borderRadius: 5,
3002
+ width: 0,
3003
+ height: 0
3004
+ },
3005
+ props
3006
+ );
3007
+ const style = () => Object.entries({
3008
+ fill: _props.color,
3009
+ stroke: _props.strokeColor,
3010
+ "stroke-width": _props.strokeWidth
3011
+ }).filter(([_, value]) => value !== void 0).reduce((acc, [key, value]) => {
3012
+ acc[key] = value;
3013
+ return acc;
3014
+ }, {});
3015
+ return <rect
3016
+ class={clsx15("solid-flow__minimap-node", { selected: _props.selected }, _props.class)}
3017
+ x={_props.x}
3018
+ y={_props.y}
3019
+ rx={_props.borderRadius}
3020
+ ry={_props.borderRadius}
3021
+ width={_props.width}
3022
+ height={_props.height}
3023
+ shape-rendering={_props.shapeRendering}
3024
+ style={style()}
3025
+ />;
3026
+ };
3027
+
3028
+ // src/components/graph/plugins/minimap/MiniMap.tsx
3029
+ var getAttrFunction = (func) => func instanceof Function ? func : () => func;
3030
+ var MiniMap = (props) => {
3031
+ const { store, nodeLookup } = useInternalSolidFlow();
3032
+ const _props = mergeProps16(
3033
+ {
3034
+ position: "bottom-right",
3035
+ nodeClass: "",
3036
+ nodeStrokeColor: "transparent",
3037
+ pannable: true,
3038
+ zoomable: true,
3039
+ width: 200,
3040
+ height: 150,
3041
+ nodeBorderRadius: 5,
3042
+ nodeStrokeWidth: 2,
3043
+ style: {}
3044
+ },
3045
+ props
3046
+ );
3047
+ const [local, paneProps] = splitProps8(_props, [
3048
+ "class",
3049
+ "style",
3050
+ "position",
3051
+ "nodeClass",
3052
+ "nodeStrokeColor",
3053
+ "nodeColor",
3054
+ "pannable",
3055
+ "zoomable",
3056
+ "inversePan",
3057
+ "zoomStep",
3058
+ "bgColor",
3059
+ "width",
3060
+ "height",
3061
+ "maskColor",
3062
+ "maskStrokeColor",
3063
+ "maskStrokeWidth",
3064
+ "nodeBorderRadius",
3065
+ "nodeStrokeWidth"
3066
+ ]);
3067
+ const nodeColorFunc = () => local.nodeColor === void 0 ? void 0 : getAttrFunction(local.nodeColor);
3068
+ const nodeStrokeColorFunc = () => getAttrFunction(local.nodeStrokeColor);
3069
+ const nodeClassFunc = () => getAttrFunction(local.nodeClass);
3070
+ const shapeRendering = () => (
3071
+ // @ts-expect-error - TS doesn't know about chrome
3072
+ typeof window === "undefined" || !!window.chrome ? "crispEdges" : "geometricPrecision"
3073
+ );
3074
+ const labelledBy = createMemo7(() => `solid-flow__minimap-desc-${store.id}`);
3075
+ const getViewBB = () => ({
3076
+ x: -store.viewport.x / store.viewport.zoom,
3077
+ y: -store.viewport.y / store.viewport.zoom,
3078
+ width: store.width / store.viewport.zoom,
3079
+ height: store.height / store.viewport.zoom
3080
+ });
3081
+ const getBoundingRect = () => {
3082
+ const viewBB = getViewBB();
3083
+ return nodeLookup.size > 0 ? getBoundsOfRects2(getInternalNodesBounds2(nodeLookup), viewBB) : viewBB;
3084
+ };
3085
+ const getScaledWidth = () => getBoundingRect().width / local.width;
3086
+ const getScaledHeight = () => getBoundingRect().height / local.height;
3087
+ const getViewScale = () => Math.max(getScaledWidth(), getScaledHeight());
3088
+ const getViewWidth = () => getViewScale() * local.width;
3089
+ const getViewHeight = () => getViewScale() * local.height;
3090
+ const getOffset = () => 5 * getViewScale();
3091
+ const getX = () => {
3092
+ const boundingRect = getBoundingRect();
3093
+ return boundingRect.x - (getViewWidth() - boundingRect.width) / 2 - getOffset();
3094
+ };
3095
+ const getY = () => {
3096
+ const boundingRect = getBoundingRect();
3097
+ return boundingRect.y - (getViewHeight() - boundingRect.height) / 2 - getOffset();
3098
+ };
3099
+ const getViewboxWidth = () => getViewWidth() + getOffset() * 2;
3100
+ const getViewboxHeight = () => getViewHeight() + getOffset() * 2;
3101
+ const strokeWidth = () => local.maskStrokeWidth ? local.maskStrokeWidth * getViewScale() : void 0;
3102
+ let prevNodeIds = [];
3103
+ const nodeIds = () => {
3104
+ const currentNodeIds = store.nodes.map((node) => node.id);
3105
+ const currentSet = new Set(currentNodeIds);
3106
+ if (prevNodeIds.length !== currentNodeIds.length || !prevNodeIds.every((id) => currentSet.has(id))) {
3107
+ prevNodeIds = currentNodeIds;
3108
+ }
3109
+ return prevNodeIds;
3110
+ };
3111
+ return <Panel
3112
+ position={local.position}
3113
+ data-testid="solid-flow__minimap"
3114
+ class={clsx16(["solid-flow__minimap", local.class])}
3115
+ style={{
3116
+ "--xy-minimap-background-color-props": local.bgColor,
3117
+ ...local.style
3118
+ }}
3119
+ {...paneProps}
3120
+ >
3121
+ <Show13 when={store.panZoom}>
3122
+ {(panZoom) => {
3123
+ const [ref, setRef] = createSignal6();
3124
+ onMount3(() => {
3125
+ const minimap = XYMinimap({
3126
+ domNode: ref(),
3127
+ panZoom: panZoom(),
3128
+ getTransform: () => store.transform,
3129
+ getViewScale
3130
+ });
3131
+ createEffect6(() => {
3132
+ minimap.update({
3133
+ translateExtent: store.translateExtent,
3134
+ width: store.width,
3135
+ height: store.height,
3136
+ inversePan: local.inversePan,
3137
+ zoomStep: local.zoomStep,
3138
+ pannable: local.pannable,
3139
+ zoomable: local.zoomable
3140
+ });
3141
+ });
3142
+ onCleanup4(() => {
3143
+ minimap.destroy();
3144
+ });
3145
+ });
3146
+ return <svg
3147
+ ref={setRef}
3148
+ width={local.width}
3149
+ height={local.height}
3150
+ viewBox={`${getX()} ${getY()} ${getViewboxWidth()} ${getViewboxHeight()}`}
3151
+ class="solid-flow__minimap-svg"
3152
+ role="img"
3153
+ aria-labelledby={labelledBy()}
3154
+ style={{
3155
+ "--xy-minimap-mask-background-color-props": local.maskColor,
3156
+ "--xy-minimap-mask-stroke-color-props": local.maskStrokeColor,
3157
+ "--xy-minimap-mask-stroke-width-props": strokeWidth()
3158
+ }}
3159
+ >
3160
+ <title id={labelledBy()}>{store.ariaLabelConfig["minimap.ariaLabel"]}</title>
3161
+ <Index each={nodeIds()}>
3162
+ {(nodeId) => {
3163
+ const node = createMemo7(() => nodeLookup.get(nodeId()));
3164
+ const nodeVisible = () => Boolean(node() && nodeHasDimensions2(node()) && !node().hidden);
3165
+ return <Show13 when={nodeVisible() && getNodeDimensions3(node())}>
3166
+ {(nodeDimensions) => <MiniMapNode
3167
+ x={node().internals.positionAbsolute.x}
3168
+ y={node().internals.positionAbsolute.y}
3169
+ borderRadius={local.nodeBorderRadius}
3170
+ strokeWidth={local.nodeStrokeWidth}
3171
+ shapeRendering={shapeRendering()}
3172
+ width={nodeDimensions().width}
3173
+ height={nodeDimensions().height}
3174
+ selected={node().selected}
3175
+ color={nodeColorFunc()?.call(null, node())}
3176
+ strokeColor={nodeStrokeColorFunc().call(null, node())}
3177
+ class={nodeClassFunc().call(null, node())}
3178
+ />}
3179
+ </Show13>;
3180
+ }}
3181
+ </Index>
3182
+ <path
3183
+ class="solid-flow__minimap-mask"
3184
+ d={`M${getX() - getOffset()},${getY() - getOffset()}h${getViewboxWidth() + getOffset() * 2}v${getViewboxHeight() + getOffset() * 2}h${-getViewboxWidth() - getOffset() * 2}z
3185
+ M${getViewBB().x},${getViewBB().y}h${getViewBB().width}v${getViewBB().height}h${-getViewBB().width}z`}
3186
+ fill-rule="evenodd"
3187
+ pointer-events="none"
3188
+ />
3189
+ </svg>;
3190
+ }}
3191
+ </Show13>
3192
+ </Panel>;
3193
+ };
3194
+
3195
+ // src/components/graph/plugins/nodeResizer/NodeResizer.tsx
3196
+ import {
3197
+ XY_RESIZER_HANDLE_POSITIONS,
3198
+ XY_RESIZER_LINE_POSITIONS
3199
+ } from "@xyflow/system";
3200
+ import { For as For4, mergeProps as mergeProps18, Show as Show14, splitProps as splitProps10 } from "solid-js";
3201
+
3202
+ // src/components/graph/plugins/nodeResizer/ResizeControl.tsx
3203
+ import {
3204
+ XYResizer
3205
+ } from "@xyflow/system";
3206
+ import clsx17 from "clsx";
3207
+ import {
3208
+ createEffect as createEffect7,
3209
+ mergeProps as mergeProps17,
3210
+ onCleanup as onCleanup5,
3211
+ onMount as onMount4,
3212
+ splitProps as splitProps9
3213
+ } from "solid-js";
3214
+ import { produce as produce3 } from "solid-js/store";
3215
+ var ResizeControl = (props) => {
3216
+ const _props = mergeProps17(
3217
+ {
3218
+ variant: "handle",
3219
+ minWidth: 10,
3220
+ minHeight: 10,
3221
+ maxWidth: Number.MAX_VALUE,
3222
+ maxHeight: Number.MAX_VALUE,
3223
+ keepAspectRatio: false,
3224
+ autoScale: true,
3225
+ style: {}
3226
+ },
3227
+ props
3228
+ );
3229
+ const [local, rest] = splitProps9(_props, [
3230
+ "nodeId",
3231
+ "variant",
3232
+ "position",
3233
+ "minWidth",
3234
+ "minHeight",
3235
+ "maxWidth",
3236
+ "maxHeight",
3237
+ "keepAspectRatio",
3238
+ "autoScale",
3239
+ "onResizeStart",
3240
+ "onResize",
3241
+ "onResizeEnd",
3242
+ "shouldResize",
3243
+ "class",
3244
+ "children",
3245
+ "color",
3246
+ "style"
3247
+ ]);
3248
+ let resizeControlRef;
3249
+ const { store, nodeLookup, actions } = useInternalSolidFlow();
3250
+ const ctxNodeId = useNodeId();
3251
+ const nodeId = () => local.nodeId ?? ctxNodeId();
3252
+ const isLineVariant = () => local.variant === "line";
3253
+ const controlPosition = () => local.position ?? (isLineVariant() ? "right" : "bottom-right");
3254
+ const positionClassNames = () => controlPosition().split("-");
3255
+ onMount4(() => {
3256
+ const resizer = XYResizer({
3257
+ domNode: resizeControlRef,
3258
+ nodeId: nodeId(),
3259
+ getStoreItems: () => ({
3260
+ nodeLookup,
3261
+ transform: store.transform,
3262
+ snapGrid: store.snapGrid,
3263
+ snapToGrid: !!store.snapGrid,
3264
+ nodeOrigin: store.nodeOrigin,
3265
+ paneDomNode: store.domNode
3266
+ }),
3267
+ onChange: (change, childChanges) => {
3268
+ const changes = /* @__PURE__ */ new Map();
3269
+ const position = change.x && change.y ? { x: change.x, y: change.y } : void 0;
3270
+ changes.set(nodeId(), { ...change, position });
3271
+ for (const childChange of childChanges) {
3272
+ changes.set(childChange.id, {
3273
+ position: childChange.position
3274
+ });
3275
+ }
3276
+ actions.setNodes(
3277
+ (node) => changes.has(node.id),
3278
+ produce3((node) => {
3279
+ const nodeChange = changes.get(node.id);
3280
+ node.width = nodeChange.width;
3281
+ node.height = nodeChange.height;
3282
+ node.position = {
3283
+ x: nodeChange.position?.x ?? node.position.x,
3284
+ y: nodeChange.position?.y ?? node.position.y
3285
+ };
3286
+ })
3287
+ );
3288
+ }
3289
+ });
3290
+ createEffect7(() => {
3291
+ resizer.update({
3292
+ controlPosition: controlPosition(),
3293
+ boundaries: {
3294
+ minWidth: local.minWidth,
3295
+ minHeight: local.minHeight,
3296
+ maxWidth: local.maxWidth,
3297
+ maxHeight: local.maxHeight
3298
+ },
3299
+ keepAspectRatio: !!local.keepAspectRatio,
3300
+ onResizeStart: local.onResizeStart,
3301
+ onResize: local.onResize,
3302
+ onResizeEnd: local.onResizeEnd,
3303
+ shouldResize: local.shouldResize
3304
+ });
3305
+ });
3306
+ onCleanup5(() => {
3307
+ resizer.destroy();
3308
+ });
3309
+ });
3310
+ return <div
3311
+ ref={resizeControlRef}
3312
+ class={clsx17([
3313
+ "solid-flow__resize-control",
3314
+ local.variant,
3315
+ store.noDragClass,
3316
+ ...positionClassNames(),
3317
+ local.class
3318
+ ])}
3319
+ style={{
3320
+ "border-color": isLineVariant() ? local.color : void 0,
3321
+ "background-color": isLineVariant() ? void 0 : local.color,
3322
+ scale: isLineVariant() || !local.autoScale ? void 0 : Math.max(1 / store.viewport.zoom, 1),
3323
+ ...local.style
3324
+ }}
3325
+ {...rest}
3326
+ >
3327
+ {local.children}
3328
+ </div>;
3329
+ };
3330
+
3331
+ // src/components/graph/plugins/nodeResizer/NodeResizer.tsx
3332
+ var NodeResizer = (props) => {
3333
+ const _props = mergeProps18(
3334
+ {
3335
+ autoScale: true,
3336
+ visible: true
3337
+ },
3338
+ props
3339
+ );
3340
+ const [local, rest] = splitProps10(props, ["handleClass", "handleStyle", "lineClass", "lineStyle"]);
3341
+ return <Show14 when={_props.visible}>
3342
+ <For4 each={XY_RESIZER_LINE_POSITIONS}>
3343
+ {(position) => <ResizeControl
3344
+ variant="line"
3345
+ position={position}
3346
+ class={local.lineClass}
3347
+ style={local.lineStyle}
3348
+ {...rest}
3349
+ />}
3350
+ </For4>
3351
+ <For4 each={XY_RESIZER_HANDLE_POSITIONS}>
3352
+ {(position) => <ResizeControl
3353
+ position={position}
3354
+ class={local.handleClass}
3355
+ style={local.handleStyle}
3356
+ {...rest}
3357
+ />}
3358
+ </For4>
3359
+ </Show14>;
3360
+ };
3361
+
3362
+ // src/components/graph/plugins/NodeToolbar.tsx
3363
+ import { getNodeToolbarTransform } from "@xyflow/system";
3364
+ import { mergeProps as mergeProps19, Show as Show15, splitProps as splitProps11, useContext as useContext6 } from "solid-js";
3365
+ import { Portal as Portal3 } from "solid-js/web";
3366
+
3367
+ // src/hooks/useConnection.tsx
3368
+ function useConnection() {
3369
+ const { store } = useInternalSolidFlow();
3370
+ const connection = () => store.connection;
3371
+ return connection;
3372
+ }
3373
+
3374
+ // src/hooks/useGraph.ts
3375
+ function useNodes() {
3376
+ const { store } = useInternalSolidFlow();
3377
+ return () => store.nodes;
3378
+ }
3379
+ function useEdges() {
3380
+ const { store } = useInternalSolidFlow();
3381
+ return () => store.edges;
3382
+ }
3383
+ function useViewport() {
3384
+ const { store } = useInternalSolidFlow();
3385
+ return () => store.viewport;
3386
+ }
3387
+
3388
+ // src/hooks/useHandleEdgeSelect.tsx
3389
+ import "@xyflow/system";
3390
+ import { batch as batch6 } from "solid-js";
3391
+ function useHandleEdgeSelect() {
3392
+ const { store, edgeLookup, actions } = useInternalSolidFlow();
3393
+ return (id) => {
3394
+ const edge = edgeLookup.get(id);
3395
+ if (!edge) {
3396
+ return;
3397
+ }
3398
+ const selectable = edge.selectable || store.elementsSelectable && typeof edge.selectable === "undefined";
3399
+ if (selectable) {
3400
+ batch6(() => {
3401
+ actions.setSelectionRect(void 0);
3402
+ actions.setSelectionRectMode(void 0);
3403
+ if (!edge.selected) {
3404
+ actions.addSelectedEdges([id]);
3405
+ } else if (edge.selected && store.multiselectionKeyPressed) {
3406
+ actions.unselectNodesAndEdges({ nodes: [], edges: [edge] });
3407
+ }
3408
+ });
3409
+ }
3410
+ };
3411
+ }
3412
+
3413
+ // src/hooks/useInternalNode.tsx
3414
+ function useInternalNode(id) {
3415
+ const { nodeLookup } = useInternalSolidFlow();
3416
+ return () => nodeLookup.get(id());
3417
+ }
3418
+
3419
+ // src/hooks/useNodeConnections.ts
3420
+ import { areConnectionMapsEqual as areConnectionMapsEqual2 } from "@xyflow/system";
3421
+ import { createEffect as createEffect8, createSignal as createSignal7, useContext as useContext5 } from "solid-js";
3422
+ var useNodeConnections = (params) => {
3423
+ const { connectionLookup } = useInternalSolidFlow();
3424
+ const ctxNodeId = () => {
3425
+ const id2 = useContext5(NodeIdContext);
3426
+ return id2 ? id2() : "";
3427
+ };
3428
+ const id = () => params().handleId;
3429
+ const type = () => params().handleType;
3430
+ const nodeId = () => params().id ?? ctxNodeId();
3431
+ const [connections, setConnections] = createSignal7([]);
3432
+ const lookupKey = () => `${nodeId()}${type() ? id() ? `-${type()}-${id()}` : `-${type()}` : ""}`;
3433
+ createEffect8((prevConnections) => {
3434
+ const nextConnections = connectionLookup.get(lookupKey());
3435
+ if (!areConnectionMapsEqual2(nextConnections, prevConnections)) {
3436
+ prevConnections = nextConnections;
3437
+ setConnections(Array.from(prevConnections?.values() ?? []));
3438
+ }
3439
+ return nextConnections;
3440
+ });
3441
+ return connections;
3442
+ };
3443
+
3444
+ // src/hooks/useNodesData.ts
3445
+ import { shallowNodeData } from "@xyflow/system";
3446
+ import { createMemo as createMemo8 } from "solid-js";
3447
+ function useNodesData(nodeIds) {
3448
+ const { nodeLookup } = useInternalSolidFlow();
3449
+ let prevNodesData = [];
3450
+ const result = createMemo8(() => {
3451
+ const nodesData = [];
3452
+ const idValues = nodeIds();
3453
+ if (!idValues) return void 0;
3454
+ const ids = Array.isArray(idValues) ? idValues : [idValues];
3455
+ for (const nodeId of ids) {
3456
+ const node = nodeLookup.get(nodeId)?.internals.userNode;
3457
+ if (!node) continue;
3458
+ nodesData.push({
3459
+ id: node.id,
3460
+ type: node.type,
3461
+ data: node.data
3462
+ });
3463
+ }
3464
+ if (!shallowNodeData(nodesData, prevNodesData)) {
3465
+ prevNodesData = nodesData;
3466
+ }
3467
+ return Array.isArray(idValues) ? nodesData : nodesData[0];
3468
+ });
3469
+ return result;
3470
+ }
3471
+
3472
+ // src/hooks/useSolidFlow.tsx
3473
+ import {
3474
+ evaluateAbsolutePosition,
3475
+ getElementsToRemove,
3476
+ getNodesBounds,
3477
+ getOverlappingArea,
3478
+ getViewportForBounds as getViewportForBounds2,
3479
+ isRectObject,
3480
+ nodeToRect as nodeToRect2,
3481
+ pointToRendererPoint as pointToRendererPoint2,
3482
+ rendererPointToPoint
3483
+ } from "@xyflow/system";
3484
+ import { batch as batch7 } from "solid-js";
3485
+ import { unwrap as unwrap2 } from "solid-js/store";
3486
+ function useSolidFlow() {
3487
+ const { store, actions, nodeLookup, edgeLookup, connectionLookup } = useInternalSolidFlow();
3488
+ const getNodeRect = (node) => {
3489
+ const nodeToUse = isNode(node) ? node : nodeLookup.get(node.id);
3490
+ const position = nodeToUse.parentId ? evaluateAbsolutePosition(
3491
+ nodeToUse.position,
3492
+ nodeToUse.measured,
3493
+ nodeToUse.parentId,
3494
+ nodeLookup,
3495
+ store.nodeOrigin
3496
+ ) : nodeToUse.position;
3497
+ const nodeWithPosition = {
3498
+ ...nodeToUse,
3499
+ position,
3500
+ width: nodeToUse.measured?.width ?? nodeToUse.width,
3501
+ height: nodeToUse.measured?.height ?? nodeToUse.height
3502
+ };
3503
+ return nodeToRect2(nodeWithPosition);
3504
+ };
3505
+ const updateNode = (id, nodeUpdate, options = { replace: false }) => {
3506
+ actions.setNodes(
3507
+ (node) => node.id === id,
3508
+ (node) => {
3509
+ const nextNode = typeof nodeUpdate === "function" ? nodeUpdate(node) : nodeUpdate;
3510
+ return options?.replace && isNode(nextNode) ? nextNode : { ...node, ...nextNode };
3511
+ }
3512
+ );
3513
+ };
3514
+ const updateEdge = (id, edgeUpdate, options = { replace: false }) => {
3515
+ actions.setEdges(
3516
+ (edge) => edge.id === id,
3517
+ (edge) => {
3518
+ const nextEdge = typeof edgeUpdate === "function" ? edgeUpdate(edge) : edgeUpdate;
3519
+ return options.replace && isEdge(nextEdge) ? nextEdge : { ...edge, ...nextEdge };
3520
+ }
3521
+ );
3522
+ };
3523
+ const getInternalNode = (id) => nodeLookup.get(id);
3524
+ const addNodes = (payload) => {
3525
+ const newNodes = Array.isArray(payload) ? payload : [payload];
3526
+ actions.setNodes((nodes) => [...nodes, ...newNodes]);
3527
+ };
3528
+ const addEdges = (payload) => {
3529
+ const newEdges = Array.isArray(payload) ? payload : [payload];
3530
+ actions.setEdges((edges) => [...edges, ...newEdges]);
3531
+ };
3532
+ return {
3533
+ zoomIn: actions.zoomIn,
3534
+ zoomOut: actions.zoomOut,
3535
+ getInternalNode,
3536
+ setCenter: actions.setCenter,
3537
+ fitView: actions.fitView,
3538
+ getNode: (id) => getInternalNode(id)?.internals.userNode,
3539
+ getNodes: (ids) => !ids ? store.nodes : getElements(nodeLookup, ids),
3540
+ getEdge: (id) => edgeLookup.get(id),
3541
+ getEdges: (ids) => !ids ? store.edges : getElements(edgeLookup, ids),
3542
+ addNodes,
3543
+ addEdges,
3544
+ getViewport: () => unwrap2(store.viewport),
3545
+ setViewport: async (nextViewport, options) => {
3546
+ const currentViewport = store.viewport;
3547
+ if (!store.panZoom) {
3548
+ return Promise.resolve(false);
3549
+ }
3550
+ await store.panZoom.setViewport(
3551
+ {
3552
+ x: nextViewport.x ?? currentViewport.x,
3553
+ y: nextViewport.y ?? currentViewport.y,
3554
+ zoom: nextViewport.zoom ?? currentViewport.zoom
3555
+ },
3556
+ options
3557
+ );
3558
+ return Promise.resolve(true);
3559
+ },
3560
+ getZoom: () => store.viewport.zoom,
3561
+ setZoom: (zoomLevel, options) => {
3562
+ const panZoom = store.panZoom;
3563
+ return panZoom ? panZoom.scaleTo(zoomLevel, { duration: options?.duration }) : Promise.resolve(false);
3564
+ },
3565
+ fitBounds: async (bounds, options) => {
3566
+ if (!store.panZoom) {
3567
+ return Promise.resolve(false);
3568
+ }
3569
+ const viewport = getViewportForBounds2(
3570
+ bounds,
3571
+ store.width,
3572
+ store.height,
3573
+ store.minZoom,
3574
+ store.maxZoom,
3575
+ options?.padding ?? 0.1
3576
+ );
3577
+ await store.panZoom.setViewport(viewport, {
3578
+ duration: options?.duration,
3579
+ ease: options?.ease,
3580
+ interpolate: options?.interpolate
3581
+ });
3582
+ return Promise.resolve(true);
3583
+ },
3584
+ getIntersectingNodes: (nodeOrRect, partially = true, nodesToIntersect) => {
3585
+ const isRect = isRectObject(nodeOrRect);
3586
+ const nodeRect = isRect ? nodeOrRect : getNodeRect(nodeOrRect);
3587
+ if (!nodeRect) {
3588
+ return [];
3589
+ }
3590
+ return (nodesToIntersect || store.nodes).filter((n) => {
3591
+ const internalNode = nodeLookup.get(n.id);
3592
+ if (!internalNode || !isRect && n.id === nodeOrRect.id) {
3593
+ return false;
3594
+ }
3595
+ const currNodeRect = nodeToRect2(internalNode);
3596
+ const overlappingArea = getOverlappingArea(currNodeRect, nodeRect);
3597
+ const partiallyVisible = partially && overlappingArea > 0;
3598
+ return partiallyVisible || overlappingArea >= nodeRect.width * nodeRect.height;
3599
+ });
3600
+ },
3601
+ isNodeIntersecting: (nodeOrRect, area, partially = true) => {
3602
+ const isRect = isRectObject(nodeOrRect);
3603
+ const nodeRect = isRect ? nodeOrRect : getNodeRect(nodeOrRect);
3604
+ if (!nodeRect) {
3605
+ return false;
3606
+ }
3607
+ const overlappingArea = getOverlappingArea(nodeRect, area);
3608
+ const partiallyVisible = partially && overlappingArea > 0;
3609
+ return partiallyVisible || overlappingArea >= nodeRect.width * nodeRect.height;
3610
+ },
3611
+ deleteElements: async ({ nodes: nodesToRemove = [], edges: edgesToRemove = [] }) => {
3612
+ const { nodes: matchingNodes, edges: matchingEdges } = await getElementsToRemove({
3613
+ nodesToRemove,
3614
+ edgesToRemove,
3615
+ nodes: store.nodes,
3616
+ edges: store.edges,
3617
+ onBeforeDelete: store.onBeforeDelete
3618
+ });
3619
+ batch7(() => {
3620
+ if (matchingEdges) {
3621
+ const remmainingEdges = store.edges.filter(
3622
+ (edge) => !matchingEdges.some(({ id }) => id === edge.id)
3623
+ );
3624
+ store.onEdgesDelete?.(matchingEdges);
3625
+ actions.setEdges(remmainingEdges);
3626
+ }
3627
+ if (matchingNodes) {
3628
+ const remmainingNodes = store.nodes.filter(
3629
+ (node) => !matchingNodes.some(({ id }) => id === node.id)
3630
+ );
3631
+ store.onNodesDelete?.(matchingNodes);
3632
+ actions.setNodes(remmainingNodes);
3633
+ }
3634
+ });
3635
+ return {
3636
+ deletedNodes: matchingNodes,
3637
+ deletedEdges: matchingEdges
3638
+ };
3639
+ },
3640
+ screenToFlowPosition: (position, options = { snapToGrid: true }) => {
3641
+ if (!store.domNode) {
3642
+ return position;
3643
+ }
3644
+ const _snapGrid = options.snapToGrid ? store.snapGrid : false;
3645
+ const { x, y, zoom } = store.viewport;
3646
+ const { x: domX, y: domY } = store.domNode.getBoundingClientRect();
3647
+ const correctedPosition = {
3648
+ x: position.x - domX,
3649
+ y: position.y - domY
3650
+ };
3651
+ return pointToRendererPoint2(
3652
+ correctedPosition,
3653
+ [x, y, zoom],
3654
+ _snapGrid !== null,
3655
+ _snapGrid || [1, 1]
3656
+ );
3657
+ },
3658
+ /**
3659
+ *
3660
+ * @param position
3661
+ * @returns
3662
+ */
3663
+ flowToScreenPosition: (position) => {
3664
+ if (!store.domNode) {
3665
+ return position;
3666
+ }
3667
+ const { x, y, zoom } = store.viewport;
3668
+ const { x: domX, y: domY } = store.domNode.getBoundingClientRect();
3669
+ const rendererPosition = rendererPointToPoint(position, [x, y, zoom]);
3670
+ return {
3671
+ x: rendererPosition.x + domX,
3672
+ y: rendererPosition.y + domY
3673
+ };
3674
+ },
3675
+ toObject: () => {
3676
+ return structuredClone({
3677
+ nodes: [...unwrap2(store.nodes)],
3678
+ edges: [...unwrap2(store.edges)],
3679
+ viewport: { ...unwrap2(store.viewport) }
3680
+ });
3681
+ },
3682
+ updateNode,
3683
+ updateNodeData: (id, dataUpdate, options) => {
3684
+ const node = nodeLookup.get(id)?.internals.userNode;
3685
+ if (!node) {
3686
+ return;
3687
+ }
3688
+ const nextData = typeof dataUpdate === "function" ? dataUpdate(node) : dataUpdate;
3689
+ updateNode(id, (node2) => ({
3690
+ ...node2,
3691
+ data: options?.replace ? nextData : { ...node2.data, ...nextData }
3692
+ }));
3693
+ },
3694
+ updateEdge,
3695
+ getNodesBounds: (nodes) => {
3696
+ return getNodesBounds(nodes, { nodeLookup, nodeOrigin: store.nodeOrigin });
3697
+ },
3698
+ getHandleConnections: ({ type, id, nodeId }) => Array.from(connectionLookup.get(`${nodeId}-${type}-${id ?? null}`)?.values() ?? [])
3699
+ };
3700
+ }
3701
+ function getElements(lookup, ids) {
3702
+ const result = [];
3703
+ for (const id of ids) {
3704
+ const item = lookup.get(id);
3705
+ if (item) {
3706
+ const element = "internals" in item ? item.internals?.userNode : item;
3707
+ result.push(element);
3708
+ }
3709
+ }
3710
+ return result;
3711
+ }
3712
+
3713
+ // src/hooks/useUpdateNodeInternals.ts
3714
+ function useUpdateNodeInternals() {
3715
+ const { store, actions } = useInternalSolidFlow();
3716
+ const updateInternals = (id) => {
3717
+ const updateIds = Array.isArray(id) ? id : [id];
3718
+ const updates = [];
3719
+ for (const updateId of updateIds) {
3720
+ const nodeElement = store.domNode?.querySelector(
3721
+ `.solid-flow__node[data-id="${updateId}"]`
3722
+ );
3723
+ if (!nodeElement) continue;
3724
+ updates.push([updateId, { id: updateId, nodeElement, force: true }]);
3725
+ }
3726
+ actions.requestUpdateNodeInternals(updates);
3727
+ };
3728
+ return updateInternals;
3729
+ }
3730
+
3731
+ // src/components/graph/plugins/NodeToolbar.tsx
3732
+ var NodeToolbar = (props) => {
3733
+ const { store } = useInternalSolidFlow();
3734
+ const { getNodes, getNodesBounds: getNodesBounds3, getInternalNode } = useSolidFlow();
3735
+ const _props = mergeProps19(
3736
+ {
3737
+ offset: 10,
3738
+ position: "top",
3739
+ align: "center",
3740
+ style: {}
3741
+ },
3742
+ props
3743
+ );
3744
+ const [local, divProps] = splitProps11(_props, [
3745
+ "nodeId",
3746
+ "position",
3747
+ "align",
3748
+ "offset",
3749
+ "isVisible",
3750
+ "style",
3751
+ "children"
3752
+ ]);
3753
+ const ctxNodeId = () => {
3754
+ const id = useContext6(NodeIdContext);
3755
+ return id ? id() : "";
3756
+ };
3757
+ const toolbarNodes = () => {
3758
+ const nodeIds = Array.isArray(local.nodeId) ? local.nodeId : [local.nodeId ?? ctxNodeId()];
3759
+ return nodeIds.reduce((res, nodeId) => {
3760
+ const node = getInternalNode(nodeId);
3761
+ if (node) res.push(node);
3762
+ return res;
3763
+ }, []);
3764
+ };
3765
+ const transform = () => {
3766
+ const nodeRect = getNodesBounds3(toolbarNodes());
3767
+ return !nodeRect ? "" : getNodeToolbarTransform(
3768
+ nodeRect,
3769
+ store.viewport,
3770
+ local.position,
3771
+ local.offset,
3772
+ local.align
3773
+ );
3774
+ };
3775
+ const zIndex = () => {
3776
+ const nodes = toolbarNodes();
3777
+ return nodes.length === 0 ? 1 : Math.max(...nodes.map((node) => (node.internals.z || 5) + 1));
3778
+ };
3779
+ const selectedNodesCount = () => getNodes().filter((node) => node.selected).length;
3780
+ const isActive = () => {
3781
+ const nodes = toolbarNodes();
3782
+ return typeof local.isVisible === "boolean" ? local.isVisible : nodes.length === 1 && Boolean(nodes[0].selected) && selectedNodesCount() === 1;
3783
+ };
3784
+ const showPortal = () => Boolean(store.domNode && isActive() && toolbarNodes().length > 0);
3785
+ return <Show15 when={showPortal()}>
3786
+ <Portal3 mount={store.domNode}>
3787
+ <div
3788
+ class="solid-flow__node-toolbar"
3789
+ data-id={toolbarNodes().reduce((acc, node) => `${acc}${node.id} `, "").trim()}
3790
+ style={{
3791
+ // TODO: Add hideOnSSR display style from Svelte implementation
3792
+ position: "absolute",
3793
+ transform: transform(),
3794
+ "z-index": zIndex(),
3795
+ ...local.style
3796
+ }}
3797
+ {...divProps}
3798
+ >
3799
+ {local.children}
173
3800
  </div>
174
- </Fa>
175
- </Va>};import{getInternalNodesBounds as Za,isNumeric as Dn}from"@xyflow/system";import $a from"clsx";import{createEffect as Ua,createSignal as Ja,Show as Ga}from"solid-js";import{mergeProps as Ya,Show as Wa}from"solid-js";var _e=e=>{let o=Ya({isVisible:!0},e),t=()=>({...o.width!=null&&{width:typeof o.width=="string"?o.width:J(o.width)},...o.height!=null&&{height:typeof o.height=="string"?o.height:J(o.height)},...o.x!=null&&o.y!=null&&{transform:`translate(${e.x}px, ${e.y}px)`}});return<Wa when={o.isVisible}>
176
- <div class="solid-flow__selection"style={t()}/>
177
- </Wa>};var Mt=e=>{let{store:o,nodeLookup:t,actions:N}=z(),[S,P]=Ja(),x=()=>o.selectionRectMode==="nodes"?Za(t,{filter:v=>!!v.selected}):null;Ua(()=>{o.disableKeyboardA11y||S()?.focus({preventScroll:!0})});let b=v=>{let E=o.nodes.filter(w=>w.selected);e.onSelectionContextMenu?.({nodes:E,event:v})},C=v=>{let E=o.nodes.filter(w=>w.selected);e.onSelectionClick?.({nodes:E,event:v})};Ze(S,()=>({disabled:!1,onDrag:(v,E,w,I)=>{e.onNodeDrag?.({event:v,targetNode:null,nodes:I})},onDragStart:(v,E,w,I)=>{e.onNodeDragStart?.({event:v,targetNode:null,nodes:I})},onDragStop:(v,E,w,I)=>{e.onNodeDragStop?.({event:v,targetNode:null,nodes:I})}}));let T=v=>{let E=Xe[v.key];E&&(v.preventDefault(),N.moveSelectedNodes(E,v.shiftKey?4:1))};return<Ga when={o.selectionRectMode==="nodes"&&x()&&Dn(x()?.x)&&Dn(x()?.y)}>
178
- <div ref={P}class={$a("solid-flow__selection-wrapper",o.noPanClass)}style={{width:J(x()?.width),height:J(x()?.height),transform:`translate(${x()?.x}px, ${x()?.y}px)`}}onClick={C}onContextMenu={b}role={o.disableKeyboardA11y?void 0:"button"}tabIndex={o.disableKeyboardA11y?void 0:-1}onKeyDown={o.disableKeyboardA11y?void 0:T}>
179
- <_e width="100%"height="100%"x={0}y={0}/>
3801
+ </Portal3>
3802
+ </Show15>;
3803
+ };
3804
+
3805
+ // src/components/graph/selection/NodeSelection.tsx
3806
+ import { getInternalNodesBounds as getInternalNodesBounds3, isNumeric as isNumeric2 } from "@xyflow/system";
3807
+ import clsx18 from "clsx";
3808
+ import { createEffect as createEffect9, createSignal as createSignal8, Show as Show17 } from "solid-js";
3809
+
3810
+ // src/components/graph/selection/Selection.tsx
3811
+ import { mergeProps as mergeProps20, Show as Show16 } from "solid-js";
3812
+ var Selection = (props) => {
3813
+ const _props = mergeProps20({ isVisible: true }, props);
3814
+ const styles = () => ({
3815
+ ..._props.width != null && {
3816
+ width: typeof _props.width === "string" ? _props.width : toPxString(_props.width)
3817
+ },
3818
+ ..._props.height != null && {
3819
+ height: typeof _props.height === "string" ? _props.height : toPxString(_props.height)
3820
+ },
3821
+ ..._props.x != null && _props.y != null && {
3822
+ transform: `translate(${props.x}px, ${props.y}px)`
3823
+ }
3824
+ });
3825
+ return <Show16 when={_props.isVisible}>
3826
+ <div class="solid-flow__selection" style={styles()} />
3827
+ </Show16>;
3828
+ };
3829
+
3830
+ // src/components/graph/selection/NodeSelection.tsx
3831
+ var NodeSelection = (props) => {
3832
+ const { store, nodeLookup, actions } = useInternalSolidFlow();
3833
+ const [ref, setRef] = createSignal8();
3834
+ const bounds = () => {
3835
+ if (store.selectionRectMode === "nodes") {
3836
+ return getInternalNodesBounds3(nodeLookup, {
3837
+ filter: (node) => !!node.selected
3838
+ });
3839
+ }
3840
+ return null;
3841
+ };
3842
+ createEffect9(() => {
3843
+ if (!store.disableKeyboardA11y) {
3844
+ ref()?.focus({ preventScroll: true });
3845
+ }
3846
+ });
3847
+ const onContextMenu = (event) => {
3848
+ const selectedNodes = store.nodes.filter((n) => n.selected);
3849
+ props.onSelectionContextMenu?.({ nodes: selectedNodes, event });
3850
+ };
3851
+ const onClick = (event) => {
3852
+ const selectedNodes = store.nodes.filter((n) => n.selected);
3853
+ props.onSelectionClick?.({ nodes: selectedNodes, event });
3854
+ };
3855
+ createDraggable_default(ref, () => ({
3856
+ disabled: false,
3857
+ onDrag: (event, _, __, nodes) => {
3858
+ props.onNodeDrag?.({ event, targetNode: null, nodes });
3859
+ },
3860
+ onDragStart: (event, _, __, nodes) => {
3861
+ props.onNodeDragStart?.({ event, targetNode: null, nodes });
3862
+ },
3863
+ onDragStop: (event, _, __, nodes) => {
3864
+ props.onNodeDragStop?.({ event, targetNode: null, nodes });
3865
+ }
3866
+ }));
3867
+ const onKeyDown = (event) => {
3868
+ const diff = ARROW_KEY_DIFFS[event.key];
3869
+ if (!diff) return;
3870
+ event.preventDefault();
3871
+ actions.moveSelectedNodes(diff, event.shiftKey ? 4 : 1);
3872
+ };
3873
+ return <Show17
3874
+ when={store.selectionRectMode === "nodes" && bounds() && isNumeric2(bounds()?.x) && isNumeric2(bounds()?.y)}
3875
+ >
3876
+ <div
3877
+ ref={setRef}
3878
+ class={clsx18("solid-flow__selection-wrapper", store.noPanClass)}
3879
+ style={{
3880
+ width: toPxString(bounds()?.width),
3881
+ height: toPxString(bounds()?.height),
3882
+ transform: `translate(${bounds()?.x}px, ${bounds()?.y}px)`
3883
+ }}
3884
+ onClick={onClick}
3885
+ onContextMenu={onContextMenu}
3886
+ role={store.disableKeyboardA11y ? void 0 : "button"}
3887
+ tabIndex={store.disableKeyboardA11y ? void 0 : -1}
3888
+ onKeyDown={store.disableKeyboardA11y ? void 0 : onKeyDown}
3889
+ >
3890
+ <Selection width="100%" height="100%" x={0} y={0} />
180
3891
  </div>
181
- </Ga>};import{createResizeObserver as dl}from"@solid-primitives/resize-observer";import{infiniteExtent as al,isMacOs as Rn}from"@xyflow/system";import ll from"clsx";import{batch as cl,createEffect as pl,mergeProps as gl,onCleanup as ml,onMount as ul,splitProps as yl,useContext as fl}from"solid-js";import{Show as Qa}from"solid-js";var It=e=><Qa when={!e.proOptions?.hideAttribution}>
182
- <Pe position={e.position??"bottom-right"}class="solid-flow__attribution"data-message="Feel free to remove the attribution or check out how you could support us: https://solidflow.dev/support-us">
183
- <a href="https://solidflow.dev"target="_blank"rel="noopener noreferrer"aria-label="Solid Flow attribution">
3892
+ </Show17>;
3893
+ };
3894
+
3895
+ // src/components/SolidFlow/component.tsx
3896
+ import { createResizeObserver } from "@solid-primitives/resize-observer";
3897
+ import { infiniteExtent as infiniteExtent4, isMacOs as isMacOs2 } from "@xyflow/system";
3898
+ import clsx19 from "clsx";
3899
+ import {
3900
+ batch as batch9,
3901
+ createEffect as createEffect10,
3902
+ mergeProps as mergeProps22,
3903
+ onCleanup as onCleanup7,
3904
+ onMount as onMount6,
3905
+ splitProps as splitProps12,
3906
+ useContext as useContext7
3907
+ } from "solid-js";
3908
+
3909
+ // src/components/utility/Attribution.tsx
3910
+ import { Show as Show18 } from "solid-js";
3911
+ var Attribution = (props) => {
3912
+ return <Show18 when={!props.proOptions?.hideAttribution}>
3913
+ <Panel
3914
+ position={props.position ?? "bottom-right"}
3915
+ class="solid-flow__attribution"
3916
+ data-message="Feel free to remove the attribution or check out how you could support us: https://solidflow.dev/support-us"
3917
+ >
3918
+ <a
3919
+ href="https://solidflow.dev"
3920
+ target="_blank"
3921
+ rel="noopener noreferrer"
3922
+ aria-label="Solid Flow attribution"
3923
+ >
184
3924
  Solid Flow
185
3925
  </a>
186
- </Pe>
187
- </Qa>;import{isInputDOMNode as el,isMacOs as On}from"@xyflow/system";import{batch as kt,mergeProps as ol,onCleanup as tl,onMount as nl}from"solid-js";function zn(e){return e!==null&&typeof e=="object"}function rl(e){return zn(e)?e.modifier||[]:[]}function il(e){return e==null?"":zn(e)?e.key:e}function sl(e,o){if(!o)return!1;let t=il(o);if(!t)return!1;let N=rl(o);if(Array.isArray(N)){let S=N.flatMap(P=>P).every(P=>{switch(P.toLowerCase()){case"meta":return e.metaKey;case"ctrl":return e.ctrlKey;case"alt":return e.altKey;case"shift":return e.shiftKey;default:return!1}});return e.key===t&&S}return e.key===t}function le(e,o){return o?(Array.isArray(o)?o:[o]).some(N=>sl(e,N)):!1}var Dt=e=>{let{store:o,actions:t}=z(),{deleteElements:N}=Po(),S=ol({selectionKey:"Shift",multiSelectionKey:On()?"Meta":"Control",deleteKey:"Backspace",panActivationKey:" ",zoomActivationKey:On()?"Meta":"Control"},e),P=()=>{kt(()=>{t.setSelectionRect(void 0),t.setSelectionKeyPressed(!1),t.setMultiselectionKeyPressed(!1),t.setDeleteKeyPressed(!1),t.setPanActivationKeyPressed(!1),t.setZoomActivationKeyPressed(!1)})},x=async()=>{let T=o.nodes.filter(I=>I.selected),v=o.edges.filter(I=>I.selected),{deletedNodes:E,deletedEdges:w}=await N({nodes:T,edges:v});(E.length>0||w.length>0)&&o.onDelete?.({nodes:E,edges:w})},b=T=>{kt(()=>{le(T,S.selectionKey)&&t.setSelectionKeyPressed(!0),le(T,S.multiSelectionKey)&&t.setMultiselectionKeyPressed(!0),le(T,S.deleteKey)&&!el(T)&&(T.ctrlKey||T.metaKey||T.shiftKey||(t.setDeleteKeyPressed(!0),x())),le(T,S.panActivationKey)&&t.setPanActivationKeyPressed(!0),le(T,S.zoomActivationKey)&&t.setZoomActivationKeyPressed(!0)})},C=T=>{kt(()=>{le(T,S.selectionKey)&&t.setSelectionKeyPressed(!1),le(T,S.multiSelectionKey)&&t.setMultiselectionKeyPressed(!1),le(T,S.deleteKey)&&t.setDeleteKeyPressed(!1),le(T,S.panActivationKey)&&t.setPanActivationKeyPressed(!1),le(T,S.zoomActivationKey)&&t.setZoomActivationKeyPressed(!1)})};return nl(()=>{window.addEventListener("keydown",b),window.addEventListener("keyup",C),window.addEventListener("blur",P),window.addEventListener("contextmenu",P),tl(()=>{window.removeEventListener("keydown",b),window.removeEventListener("keyup",C),window.removeEventListener("blur",P),window.removeEventListener("contextmenu",P)})}),null};var hl=e=>{let o,t=gl({...we(),colorMode:"light",deleteKeyCode:"Backspace",defaultViewport:{x:0,y:0,zoom:1},multiSelectionKeyCode:Rn()?"Meta":"Control",nodeClickDistance:0,panOnScroll:!1,panActivationKeyCode:"Space",preventScrolling:!0,panOnDrag:!0,panOnScrollSpeed:.5,panOnScrollMode:"free",paneClickDistance:0,reconnectRadius:10,selectionKeyCode:"Shift",selectionOnDrag:!1,translateExtent:al,zoomActivationKeyCode:Rn()?"Meta":"Control",zoomOnPinch:!0,zoomOnDoubleClick:!0,zoomOnScroll:!0},e),[N,S]=yl(t,["nodes","edges","nodeTypes","edgeTypes","width","height","fitView","fitViewOptions","nodeOrigin","nodeDragThreshold","paneClickDistance","nodeClickDistance","minZoom","maxZoom","initialViewport","viewport","translateExtent","nodeExtent","selectionKey","panActivationKey","deleteKey","multiSelectionKey","zoomActivationKey","panOnDrag","panOnScroll","panOnScrollMode","panOnScrollSpeed","selectionOnDrag","selectNodesOnDrag","preventScrolling","zoomOnScroll","zoomOnDoubleClick","zoomOnPinch","onlyRenderVisibleElements","autoPanOnConnect","autoPanOnNodeDrag","autoPanOnNodeFocus","autoPanSpeed","connectionRadius","connectionMode","connectionLineType","connectionLineComponent","connectionLineStyle","connectionLineContainerStyle","connectionDragThreshold","isValidConnection","clickConnect","reconnectRadius","selectionMode","elementsSelectable","nodesDraggable","nodesConnectable","nodesFocusable","edgesFocusable","disableKeyboardA11y","ariaLabelConfig","ariaLiveMessage","colorMode","colorModeSSR","class","style","snapGrid","defaultMarkerColor","defaultEdgeOptions","elevateNodesOnSelect","elevateEdgesOnSelect","noDragClass","noPanClass","noWheelClass","attributionPosition","proOptions","onInit","onMoveStart","onMove","onMoveEnd","onFlowError","onNodeClick","onNodeContextMenu","onNodeDrag","onNodeDragStart","onNodeDragStop","onNodePointerEnter","onNodePointerMove","onNodePointerLeave","onEdgeClick","onEdgeContextMenu","onEdgePointerEnter","onEdgePointerLeave","onPaneClick","onPaneContextMenu","onSelectionChange","onSelectionClick","onSelectionContextMenu","onSelectionDrag","onSelectionDragStart","onSelectionDragStop","onSelectionStart","onSelectionEnd","onConnect","onConnectStart","onConnectEnd","onReconnect","onReconnectStart","onReconnectEnd","onClickConnectStart","onClickConnectEnd","onBeforeConnect","onBeforeReconnect","onDelete","onBeforeDelete","deleteKeyCode","selectionKeyCode","panActivationKeyCode","multiSelectionKeyCode","zoomActivationKeyCode","children"]),P=Ae,x=fl(P)??Je(t),{store:b,actions:C}=x;ul(()=>{C.applyInitialFitView(N.fitView),cl(()=>{C.setConfig(t),C.setDomNode(o)}),dl(o,()=>{C.setWidth(o.clientWidth),C.setHeight(o.clientHeight)}),pl(()=>{C.setPaneClickDistance(N.paneClickDistance)}),ml(()=>{C.reset()})});let T=()=>({width:J(N.width),height:J(N.height),...N.style});return<div role="application"data-testid="solid-flow__wrapper"ref={o}class={ll(["solid-flow","solid-flow__container",N.class,b.colorMode])}style={T()}onScroll={v=>{v.currentTarget.scrollTo({top:0,left:0,behavior:"auto"})}}{...S}>
188
- <P.Provider value={x}>
189
- <Dt selectionKey={N.selectionKey}deleteKey={N.deleteKey}panActivationKey={N.panActivationKey}multiSelectionKey={N.multiSelectionKey}zoomActivationKey={N.zoomActivationKey}/>
190
- <Qo panOnScrollMode={N.panOnScrollMode}preventScrolling={N.preventScrolling}zoomOnScroll={N.zoomOnScroll}zoomOnDoubleClick={N.zoomOnDoubleClick}zoomOnPinch={N.zoomOnPinch}panOnScroll={N.panOnScroll}panOnDrag={N.panOnDrag}paneClickDistance={N.paneClickDistance}onMoveStart={N.onMoveStart}onMove={N.onMove}onMoveEnd={N.onMoveEnd}onViewportInitialized={N.onInit}initialViewport={N.viewport||N.initialViewport}>
191
- <Jo onPaneClick={N.onPaneClick}onPaneContextMenu={N.onPaneContextMenu}onSelectionStart={N.onSelectionStart}onSelectionEnd={N.onSelectionEnd}panOnDrag={N.panOnDrag}selectionOnDrag={N.selectionOnDrag}>
192
- <Go>
193
- <div class="solid-flow__container solid-flow__viewport-back"/>
194
- <$o reconnectRadius={N.reconnectRadius}onEdgeClick={N.onEdgeClick}onEdgeContextMenu={N.onEdgeContextMenu}onEdgePointerEnter={N.onEdgePointerEnter}onEdgePointerLeave={N.onEdgePointerLeave}defaultEdgeOptions={N.defaultEdgeOptions}/>
195
- <div class="solid-flow__container solid-flow__edge-labels"/>
196
- <St type={N.connectionLineType}component={N.connectionLineComponent}containerStyle={N.connectionLineContainerStyle}style={N.connectionLineStyle}/>
197
- <Uo nodeClickDistance={N.nodeClickDistance}onNodeClick={N.onNodeClick}onNodeContextMenu={N.onNodeContextMenu}onNodePointerEnter={N.onNodePointerEnter}onNodePointerMove={N.onNodePointerMove}onNodePointerLeave={N.onNodePointerLeave}onNodeDrag={N.onNodeDrag}onNodeDragStart={N.onNodeDragStart}onNodeDragStop={N.onNodeDragStop}/>
198
- <Mt onSelectionClick={N.onSelectionClick}onSelectionContextMenu={N.onSelectionContextMenu}onNodeDrag={N.onNodeDrag}onNodeDragStart={N.onNodeDragStart}onNodeDragStop={N.onNodeDragStop}/>
199
- </Go>
200
- <_e isVisible={!!b.selectionRect&&b.selectionRectMode==="user"}width={b.selectionRect?.width}height={b.selectionRect?.height}x={b.selectionRect?.x}y={b.selectionRect?.y}/>
201
- </Jo>
202
- </Qo>
203
- <It proOptions={N.proOptions}position={N.attributionPosition}/>
204
- <Mo/>
205
- {N.children}
206
- </P.Provider>
207
- </div>};import{mergeProps as Sl,onCleanup as Nl}from"solid-js";var Pl=e=>{let o=Sl(we(),e),t=Je(o);Nl(()=>{t.actions.reset()});let N=Ae.Provider;return<N value={t}>{e.children}</N>};import{createStore as bl}from"solid-js/store";var El=e=>{let[o,t]=bl(e);return[o,t]};import{createStore as xl}from"solid-js/store";var wl=e=>{let[o,t]=xl(e);return[o,t]};import{addEdge as ah,getBezierEdgeCenter as lh,getBezierPath as ch,getConnectedEdges as ph,getEdgeCenter as gh,getIncomers as mh,getNodesBounds as uh,getOutgoers as yh,getSmoothStepPath as fh,getStraightPath as hh,getViewportForBounds as Sh}from"@xyflow/system";import{ConnectionLineType as Ph,ConnectionMode as bh,MarkerType as Eh,PanOnScrollMode as xh,Position as wh,ResizeControlVariant as Ch,SelectionMode as Th}from"@xyflow/system";export{Pd as Background,Q as BaseEdge,kr as BezierEdge,To as BezierEdgeInternal,St as ConnectionLine,Ph as ConnectionLineType,bh as ConnectionMode,Me as ControlButton,vd as Controls,Ro as DefaultNode,De as EdgeLabel,Co as EdgeLabelRenderer,Hr as EdgeReconnectAnchor,$o as EdgeRenderer,Io as EdgeWrapper,Ao as GroupNode,Se as Handle,_o as InputNode,Wo as Marker,Zo as MarkerDefinition,Eh as MarkerType,Fd as MiniMap,Uo as NodeRenderer,Pa as NodeResizer,Mt as NodeSelection,_y as NodeToolbar,Ho as NodeWrapper,Bo as OutputNode,xh as PanOnScrollMode,Jo as Pane,Pe as Panel,wh as Position,So as ResizeControl,Ch as ResizeControlVariant,_e as Selection,Th as SelectionMode,Zr as SmoothStepEdge,ko as SmoothStepEdgeInternal,hl as SolidFlow,Pl as SolidFlowProvider,Gr as StepEdge,Do as StepEdgeInternal,ei as StraightEdge,Oo as StraightEdgeInternal,Go as Viewport,Hs as ViewportPortal,Qo as Zoom,ah as addEdge,El as createEdgeStore,wl as createNodeStore,lh as getBezierEdgeCenter,ch as getBezierPath,ph as getConnectedEdges,gh as getEdgeCenter,mh as getIncomers,uh as getNodesBounds,yh as getOutgoers,fh as getSmoothStepPath,hh as getStraightPath,Sh as getViewportForBounds,Vu as useConnection,Ea as useEdges,Uu as useHandleEdgeSelect,ju as useInternalNode,ny as useNodeConnections,ba as useNodes,ay as useNodesData,Po as useSolidFlow,hy as useUpdateNodeInternals,xa as useViewport};
3926
+ </Panel>
3927
+ </Show18>;
3928
+ };
3929
+
3930
+ // src/components/utility/KeyHandler.tsx
3931
+ import { isInputDOMNode as isInputDOMNode2, isMacOs } from "@xyflow/system";
3932
+ import { batch as batch8, mergeProps as mergeProps21, onCleanup as onCleanup6, onMount as onMount5 } from "solid-js";
3933
+ function isKeyObject(key) {
3934
+ return key !== null && typeof key === "object";
3935
+ }
3936
+ function getModifier(key) {
3937
+ return isKeyObject(key) ? key.modifier || [] : [];
3938
+ }
3939
+ function getKeyString(key) {
3940
+ if (key === null || key === void 0) {
3941
+ return "";
3942
+ }
3943
+ return isKeyObject(key) ? key.key : key;
3944
+ }
3945
+ function matchesKey(event, keyDef) {
3946
+ if (!keyDef) return false;
3947
+ const keyString = getKeyString(keyDef);
3948
+ if (!keyString) return false;
3949
+ const modifiers = getModifier(keyDef);
3950
+ if (Array.isArray(modifiers)) {
3951
+ const modifierMatch = modifiers.flatMap((mod) => mod).every((mod) => {
3952
+ switch (mod.toLowerCase()) {
3953
+ case "meta":
3954
+ return event.metaKey;
3955
+ case "ctrl":
3956
+ return event.ctrlKey;
3957
+ case "alt":
3958
+ return event.altKey;
3959
+ case "shift":
3960
+ return event.shiftKey;
3961
+ default:
3962
+ return false;
3963
+ }
3964
+ });
3965
+ return event.key === keyString && modifierMatch;
3966
+ }
3967
+ return event.key === keyString;
3968
+ }
3969
+ function matchesKeyArray(event, keyDefs) {
3970
+ if (!keyDefs) return false;
3971
+ const keys = Array.isArray(keyDefs) ? keyDefs : [keyDefs];
3972
+ return keys.some((keyDef) => matchesKey(event, keyDef));
3973
+ }
3974
+ var KeyHandler = (props) => {
3975
+ const { store, actions } = useInternalSolidFlow();
3976
+ const { deleteElements } = useSolidFlow();
3977
+ const _props = mergeProps21(
3978
+ {
3979
+ selectionKey: "Shift",
3980
+ multiSelectionKey: isMacOs() ? "Meta" : "Control",
3981
+ deleteKey: "Backspace",
3982
+ panActivationKey: " ",
3983
+ zoomActivationKey: isMacOs() ? "Meta" : "Control"
3984
+ },
3985
+ props
3986
+ );
3987
+ const resetKeysAndSelection = () => {
3988
+ batch8(() => {
3989
+ actions.setSelectionRect(void 0);
3990
+ actions.setSelectionKeyPressed(false);
3991
+ actions.setMultiselectionKeyPressed(false);
3992
+ actions.setDeleteKeyPressed(false);
3993
+ actions.setPanActivationKeyPressed(false);
3994
+ actions.setZoomActivationKeyPressed(false);
3995
+ });
3996
+ };
3997
+ const handleDelete = async () => {
3998
+ const selectedNodes = store.nodes.filter((node) => node.selected);
3999
+ const selectedEdges = store.edges.filter((edge) => edge.selected);
4000
+ const { deletedNodes, deletedEdges } = await deleteElements({
4001
+ nodes: selectedNodes,
4002
+ edges: selectedEdges
4003
+ });
4004
+ if (deletedNodes.length > 0 || deletedEdges.length > 0) {
4005
+ store.onDelete?.({
4006
+ nodes: deletedNodes,
4007
+ edges: deletedEdges
4008
+ });
4009
+ }
4010
+ };
4011
+ const handleKeyDown = (event) => {
4012
+ batch8(() => {
4013
+ if (matchesKeyArray(event, _props.selectionKey)) {
4014
+ actions.setSelectionKeyPressed(true);
4015
+ }
4016
+ if (matchesKeyArray(event, _props.multiSelectionKey)) {
4017
+ actions.setMultiselectionKeyPressed(true);
4018
+ }
4019
+ if (matchesKeyArray(event, _props.deleteKey) && !isInputDOMNode2(event)) {
4020
+ const isModifierKey = event.ctrlKey || event.metaKey || event.shiftKey;
4021
+ if (!isModifierKey) {
4022
+ actions.setDeleteKeyPressed(true);
4023
+ void handleDelete();
4024
+ }
4025
+ }
4026
+ if (matchesKeyArray(event, _props.panActivationKey)) {
4027
+ actions.setPanActivationKeyPressed(true);
4028
+ }
4029
+ if (matchesKeyArray(event, _props.zoomActivationKey)) {
4030
+ actions.setZoomActivationKeyPressed(true);
4031
+ }
4032
+ });
4033
+ };
4034
+ const handleKeyUp = (event) => {
4035
+ batch8(() => {
4036
+ if (matchesKeyArray(event, _props.selectionKey)) {
4037
+ actions.setSelectionKeyPressed(false);
4038
+ }
4039
+ if (matchesKeyArray(event, _props.multiSelectionKey)) {
4040
+ actions.setMultiselectionKeyPressed(false);
4041
+ }
4042
+ if (matchesKeyArray(event, _props.deleteKey)) {
4043
+ actions.setDeleteKeyPressed(false);
4044
+ }
4045
+ if (matchesKeyArray(event, _props.panActivationKey)) {
4046
+ actions.setPanActivationKeyPressed(false);
4047
+ }
4048
+ if (matchesKeyArray(event, _props.zoomActivationKey)) {
4049
+ actions.setZoomActivationKeyPressed(false);
4050
+ }
4051
+ });
4052
+ };
4053
+ onMount5(() => {
4054
+ window.addEventListener("keydown", handleKeyDown);
4055
+ window.addEventListener("keyup", handleKeyUp);
4056
+ window.addEventListener("blur", resetKeysAndSelection);
4057
+ window.addEventListener("contextmenu", resetKeysAndSelection);
4058
+ onCleanup6(() => {
4059
+ window.removeEventListener("keydown", handleKeyDown);
4060
+ window.removeEventListener("keyup", handleKeyUp);
4061
+ window.removeEventListener("blur", resetKeysAndSelection);
4062
+ window.removeEventListener("contextmenu", resetKeysAndSelection);
4063
+ });
4064
+ });
4065
+ return null;
4066
+ };
4067
+
4068
+ // src/components/SolidFlow/component.tsx
4069
+ var SolidFlow = (props) => {
4070
+ let domNode;
4071
+ const _props = mergeProps22(
4072
+ {
4073
+ ...getDefaultFlowStateProps(),
4074
+ colorMode: "light",
4075
+ deleteKeyCode: "Backspace",
4076
+ defaultViewport: { x: 0, y: 0, zoom: 1 },
4077
+ multiSelectionKeyCode: isMacOs2() ? "Meta" : "Control",
4078
+ nodeClickDistance: 0,
4079
+ panOnScroll: false,
4080
+ panActivationKeyCode: "Space",
4081
+ preventScrolling: true,
4082
+ panOnDrag: true,
4083
+ panOnScrollSpeed: 0.5,
4084
+ panOnScrollMode: "free",
4085
+ paneClickDistance: 0,
4086
+ reconnectRadius: 10,
4087
+ selectionKeyCode: "Shift",
4088
+ selectionOnDrag: false,
4089
+ translateExtent: infiniteExtent4,
4090
+ zoomActivationKeyCode: isMacOs2() ? "Meta" : "Control",
4091
+ zoomOnPinch: true,
4092
+ zoomOnDoubleClick: true,
4093
+ zoomOnScroll: true
4094
+ },
4095
+ props
4096
+ );
4097
+ const [flowProps, htmlProps] = splitProps12(_props, [
4098
+ // Core flow props
4099
+ "nodes",
4100
+ "edges",
4101
+ "nodeTypes",
4102
+ "edgeTypes",
4103
+ // Layout and viewport
4104
+ "width",
4105
+ "height",
4106
+ "fitView",
4107
+ "fitViewOptions",
4108
+ "nodeOrigin",
4109
+ "nodeDragThreshold",
4110
+ "paneClickDistance",
4111
+ "nodeClickDistance",
4112
+ "minZoom",
4113
+ "maxZoom",
4114
+ "initialViewport",
4115
+ "viewport",
4116
+ "translateExtent",
4117
+ "nodeExtent",
4118
+ // Interaction and behavior
4119
+ "selectionKey",
4120
+ "panActivationKey",
4121
+ "deleteKey",
4122
+ "multiSelectionKey",
4123
+ "zoomActivationKey",
4124
+ "panOnDrag",
4125
+ "panOnScroll",
4126
+ "panOnScrollMode",
4127
+ "panOnScrollSpeed",
4128
+ "selectionOnDrag",
4129
+ "selectNodesOnDrag",
4130
+ "preventScrolling",
4131
+ "zoomOnScroll",
4132
+ "zoomOnDoubleClick",
4133
+ "zoomOnPinch",
4134
+ "onlyRenderVisibleElements",
4135
+ "autoPanOnConnect",
4136
+ "autoPanOnNodeDrag",
4137
+ "autoPanOnNodeFocus",
4138
+ "autoPanSpeed",
4139
+ // Connection and validation
4140
+ "connectionRadius",
4141
+ "connectionMode",
4142
+ "connectionLineType",
4143
+ "connectionLineComponent",
4144
+ "connectionLineStyle",
4145
+ "connectionLineContainerStyle",
4146
+ "connectionDragThreshold",
4147
+ "isValidConnection",
4148
+ "clickConnect",
4149
+ "reconnectRadius",
4150
+ // Selection and accessibility
4151
+ "selectionMode",
4152
+ "elementsSelectable",
4153
+ "nodesDraggable",
4154
+ "nodesConnectable",
4155
+ "nodesFocusable",
4156
+ "edgesFocusable",
4157
+ "disableKeyboardA11y",
4158
+ "ariaLabelConfig",
4159
+ "ariaLiveMessage",
4160
+ // Styling and theming
4161
+ "colorMode",
4162
+ "colorModeSSR",
4163
+ "class",
4164
+ "style",
4165
+ "snapGrid",
4166
+ "defaultMarkerColor",
4167
+ "defaultEdgeOptions",
4168
+ "elevateNodesOnSelect",
4169
+ "elevateEdgesOnSelect",
4170
+ "noDragClass",
4171
+ "noPanClass",
4172
+ "noWheelClass",
4173
+ // Attribution and pro features
4174
+ "attributionPosition",
4175
+ "proOptions",
4176
+ // Event handlers - Flow lifecycle
4177
+ "onInit",
4178
+ "onMoveStart",
4179
+ "onMove",
4180
+ "onMoveEnd",
4181
+ "onFlowError",
4182
+ // Event handlers - Node events
4183
+ "onNodeClick",
4184
+ "onNodeContextMenu",
4185
+ "onNodeDrag",
4186
+ "onNodeDragStart",
4187
+ "onNodeDragStop",
4188
+ "onNodePointerEnter",
4189
+ "onNodePointerMove",
4190
+ "onNodePointerLeave",
4191
+ // Event handlers - Edge events
4192
+ "onEdgeClick",
4193
+ "onEdgeContextMenu",
4194
+ "onEdgePointerEnter",
4195
+ "onEdgePointerLeave",
4196
+ // Event handlers - Pane events
4197
+ "onPaneClick",
4198
+ "onPaneContextMenu",
4199
+ // Event handlers - Selection events
4200
+ "onSelectionChange",
4201
+ "onSelectionClick",
4202
+ "onSelectionContextMenu",
4203
+ "onSelectionDrag",
4204
+ "onSelectionDragStart",
4205
+ "onSelectionDragStop",
4206
+ "onSelectionStart",
4207
+ "onSelectionEnd",
4208
+ // Event handlers - Connection events
4209
+ "onConnect",
4210
+ "onConnectStart",
4211
+ "onConnectEnd",
4212
+ "onReconnect",
4213
+ "onReconnectStart",
4214
+ "onReconnectEnd",
4215
+ "onClickConnectStart",
4216
+ "onClickConnectEnd",
4217
+ "onBeforeConnect",
4218
+ "onBeforeReconnect",
4219
+ // Event handlers - Delete events
4220
+ "onDelete",
4221
+ "onBeforeDelete",
4222
+ // Legacy/deprecated props
4223
+ "deleteKeyCode",
4224
+ "selectionKeyCode",
4225
+ "panActivationKeyCode",
4226
+ "multiSelectionKeyCode",
4227
+ "zoomActivationKeyCode",
4228
+ // Special props that conflict with HTML
4229
+ "children"
4230
+ ]);
4231
+ const TypedSolidFlowContext = SolidFlowContext;
4232
+ const solidFlow = useContext7(TypedSolidFlowContext) ?? createSolidFlow(_props);
4233
+ const { store, actions } = solidFlow;
4234
+ onMount6(() => {
4235
+ actions.applyInitialFitView(flowProps.fitView);
4236
+ batch9(() => {
4237
+ actions.setConfig(_props);
4238
+ actions.setDomNode(domNode);
4239
+ });
4240
+ createResizeObserver(domNode, () => {
4241
+ actions.setWidth(domNode.clientWidth);
4242
+ actions.setHeight(domNode.clientHeight);
4243
+ });
4244
+ createEffect10(() => {
4245
+ actions.setPaneClickDistance(flowProps.paneClickDistance);
4246
+ });
4247
+ onCleanup7(() => {
4248
+ actions.reset();
4249
+ });
4250
+ });
4251
+ const rootStyle = () => ({
4252
+ width: toPxString(flowProps.width),
4253
+ height: toPxString(flowProps.height),
4254
+ ...flowProps.style
4255
+ });
4256
+ return <div
4257
+ role="application"
4258
+ data-testid="solid-flow__wrapper"
4259
+ ref={domNode}
4260
+ class={clsx19(["solid-flow", "solid-flow__container", flowProps.class, store.colorMode])}
4261
+ style={rootStyle()}
4262
+ onScroll={(e) => {
4263
+ e.currentTarget.scrollTo({ top: 0, left: 0, behavior: "auto" });
4264
+ }}
4265
+ {...htmlProps}
4266
+ >
4267
+ <TypedSolidFlowContext.Provider value={solidFlow}>
4268
+ <KeyHandler
4269
+ selectionKey={flowProps.selectionKey}
4270
+ deleteKey={flowProps.deleteKey}
4271
+ panActivationKey={flowProps.panActivationKey}
4272
+ multiSelectionKey={flowProps.multiSelectionKey}
4273
+ zoomActivationKey={flowProps.zoomActivationKey}
4274
+ />
4275
+ <Zoom
4276
+ panOnScrollMode={flowProps.panOnScrollMode}
4277
+ preventScrolling={flowProps.preventScrolling}
4278
+ zoomOnScroll={flowProps.zoomOnScroll}
4279
+ zoomOnDoubleClick={flowProps.zoomOnDoubleClick}
4280
+ zoomOnPinch={flowProps.zoomOnPinch}
4281
+ panOnScroll={flowProps.panOnScroll}
4282
+ panOnDrag={flowProps.panOnDrag}
4283
+ paneClickDistance={flowProps.paneClickDistance}
4284
+ onMoveStart={flowProps.onMoveStart}
4285
+ onMove={flowProps.onMove}
4286
+ onMoveEnd={flowProps.onMoveEnd}
4287
+ onViewportInitialized={flowProps.onInit}
4288
+ initialViewport={flowProps.viewport || flowProps.initialViewport}
4289
+ >
4290
+ <Pane
4291
+ onPaneClick={flowProps.onPaneClick}
4292
+ onPaneContextMenu={flowProps.onPaneContextMenu}
4293
+ onSelectionStart={flowProps.onSelectionStart}
4294
+ onSelectionEnd={flowProps.onSelectionEnd}
4295
+ panOnDrag={flowProps.panOnDrag}
4296
+ selectionOnDrag={flowProps.selectionOnDrag}
4297
+ >
4298
+ <Viewport>
4299
+ <div class="solid-flow__container solid-flow__viewport-back" />
4300
+ <EdgeRenderer
4301
+ reconnectRadius={flowProps.reconnectRadius}
4302
+ onEdgeClick={flowProps.onEdgeClick}
4303
+ onEdgeContextMenu={flowProps.onEdgeContextMenu}
4304
+ onEdgePointerEnter={flowProps.onEdgePointerEnter}
4305
+ onEdgePointerLeave={flowProps.onEdgePointerLeave}
4306
+ defaultEdgeOptions={flowProps.defaultEdgeOptions}
4307
+ />
4308
+ <div class="solid-flow__container solid-flow__edge-labels" />
4309
+ <ConnectionLine_default
4310
+ type={flowProps.connectionLineType}
4311
+ component={flowProps.connectionLineComponent}
4312
+ containerStyle={flowProps.connectionLineContainerStyle}
4313
+ style={flowProps.connectionLineStyle}
4314
+ />
4315
+ <NodeRenderer
4316
+ nodeClickDistance={flowProps.nodeClickDistance}
4317
+ onNodeClick={flowProps.onNodeClick}
4318
+ onNodeContextMenu={flowProps.onNodeContextMenu}
4319
+ onNodePointerEnter={flowProps.onNodePointerEnter}
4320
+ onNodePointerMove={flowProps.onNodePointerMove}
4321
+ onNodePointerLeave={flowProps.onNodePointerLeave}
4322
+ onNodeDrag={flowProps.onNodeDrag}
4323
+ onNodeDragStart={flowProps.onNodeDragStart}
4324
+ onNodeDragStop={flowProps.onNodeDragStop}
4325
+ />
4326
+ <NodeSelection
4327
+ onSelectionClick={flowProps.onSelectionClick}
4328
+ onSelectionContextMenu={flowProps.onSelectionContextMenu}
4329
+ onNodeDrag={flowProps.onNodeDrag}
4330
+ onNodeDragStart={flowProps.onNodeDragStart}
4331
+ onNodeDragStop={flowProps.onNodeDragStop}
4332
+ />
4333
+ </Viewport>
4334
+ <Selection
4335
+ isVisible={!!store.selectionRect && store.selectionRectMode === "user"}
4336
+ width={store.selectionRect?.width}
4337
+ height={store.selectionRect?.height}
4338
+ x={store.selectionRect?.x}
4339
+ y={store.selectionRect?.y}
4340
+ />
4341
+ </Pane>
4342
+ </Zoom>
4343
+ <Attribution proOptions={flowProps.proOptions} position={flowProps.attributionPosition} />
4344
+ <A11yDescriptions />
4345
+ {flowProps.children}
4346
+ </TypedSolidFlowContext.Provider>
4347
+ </div>;
4348
+ };
4349
+
4350
+ // src/components/SolidFlow/provider.tsx
4351
+ import { mergeProps as mergeProps23, onCleanup as onCleanup8 } from "solid-js";
4352
+ var SolidFlowProvider = (props) => {
4353
+ const _props = mergeProps23(getDefaultFlowStateProps(), props);
4354
+ const solidFlow = createSolidFlow(_props);
4355
+ onCleanup8(() => {
4356
+ solidFlow.actions.reset();
4357
+ });
4358
+ const ContextProvider = SolidFlowContext.Provider;
4359
+ return <ContextProvider value={solidFlow}>{props.children}</ContextProvider>;
4360
+ };
4361
+
4362
+ // src/data/createEdgeStore.tsx
4363
+ import { createStore as createStore2 } from "solid-js/store";
4364
+ var createEdgeStore = (edges) => {
4365
+ const [store, setStore] = createStore2(edges);
4366
+ return [store, setStore];
4367
+ };
4368
+
4369
+ // src/data/createNodeStore.tsx
4370
+ import { createStore as createStore3 } from "solid-js/store";
4371
+ var createNodeStore = (nodes) => {
4372
+ const [store, setStore] = createStore3(nodes);
4373
+ return [store, setStore];
4374
+ };
4375
+
4376
+ // src/index.tsx
4377
+ import {
4378
+ addEdge,
4379
+ getBezierEdgeCenter,
4380
+ getBezierPath as getBezierPath4,
4381
+ getConnectedEdges,
4382
+ getEdgeCenter,
4383
+ getIncomers,
4384
+ getNodesBounds as getNodesBounds2,
4385
+ getOutgoers,
4386
+ getSmoothStepPath as getSmoothStepPath6,
4387
+ getStraightPath as getStraightPath4,
4388
+ getViewportForBounds as getViewportForBounds3
4389
+ } from "@xyflow/system";
4390
+ import {
4391
+ ConnectionLineType,
4392
+ ConnectionMode as ConnectionMode4,
4393
+ MarkerType,
4394
+ PanOnScrollMode,
4395
+ Position as Position2,
4396
+ ResizeControlVariant,
4397
+ SelectionMode as SelectionMode2
4398
+ } from "@xyflow/system";
4399
+ export {
4400
+ Background,
4401
+ BaseEdge,
4402
+ BezierEdge,
4403
+ BezierEdgeInternal,
4404
+ ConnectionLine_default as ConnectionLine,
4405
+ ConnectionLineType,
4406
+ ConnectionMode4 as ConnectionMode,
4407
+ ControlButton,
4408
+ Controls,
4409
+ DefaultNode,
4410
+ EdgeLabel,
4411
+ EdgeLabelRenderer,
4412
+ EdgeReconnectAnchor,
4413
+ EdgeRenderer,
4414
+ EdgeWrapper,
4415
+ GroupNode,
4416
+ Handle,
4417
+ InputNode,
4418
+ Marker,
4419
+ MarkerDefinition,
4420
+ MarkerType,
4421
+ MiniMap,
4422
+ NodeRenderer,
4423
+ NodeResizer,
4424
+ NodeSelection,
4425
+ NodeToolbar,
4426
+ NodeWrapper,
4427
+ OutputNode,
4428
+ PanOnScrollMode,
4429
+ Pane,
4430
+ Panel,
4431
+ Position2 as Position,
4432
+ ResizeControl,
4433
+ ResizeControlVariant,
4434
+ Selection,
4435
+ SelectionMode2 as SelectionMode,
4436
+ SmoothStepEdge,
4437
+ SmoothStepEdgeInternal,
4438
+ SolidFlow,
4439
+ SolidFlowProvider,
4440
+ StepEdge,
4441
+ StepEdgeInternal,
4442
+ StraightEdge,
4443
+ StraightEdgeInternal,
4444
+ Viewport,
4445
+ ViewportPortal,
4446
+ Zoom,
4447
+ addEdge,
4448
+ createEdgeStore,
4449
+ createNodeStore,
4450
+ getBezierEdgeCenter,
4451
+ getBezierPath4 as getBezierPath,
4452
+ getConnectedEdges,
4453
+ getEdgeCenter,
4454
+ getIncomers,
4455
+ getNodesBounds2 as getNodesBounds,
4456
+ getOutgoers,
4457
+ getSmoothStepPath6 as getSmoothStepPath,
4458
+ getStraightPath4 as getStraightPath,
4459
+ getViewportForBounds3 as getViewportForBounds,
4460
+ useConnection,
4461
+ useEdges,
4462
+ useHandleEdgeSelect,
4463
+ useInternalNode,
4464
+ useNodeConnections,
4465
+ useNodes,
4466
+ useNodesData,
4467
+ useSolidFlow,
4468
+ useUpdateNodeInternals,
4469
+ useViewport
4470
+ };