Gradio component for svelteflow
IMPORTANT:
@svelteflow/frontendThis directory contains the Svelte-based frontend for the gradio-svelteflow component. It leverages @xyflow/svelte to render an interactive node-based diagram editor within a Gradio application.
The primary purpose of this frontend is to provide a user interface where users can create, manipulate, and connect nodes in a graph. The state of this graph (nodes and edges) is synchronized with the Gradio backend.
Index.svelte: This is the main component file that gets rendered in the Gradio interface.
<SvelteFlow> component from @xyflow/svelte.nodes and edges using Svelte stores.handleAddNode), connecting nodes (handleConnect), clicking nodes/edges, and deleting elements.gradio.dispatch) such as change, select, and submit.CustomNode.CustomNode.svelte: This is a custom node component designed for the SvelteFlow diagram.
sources and targets arrays in the node's data property.useUpdateNodeInternals from @xyflow/svelte to ensure the node's dimensions are recalculated when the number of handles changes.CustomNodeData.ts: This file defines the TypeScript type CustomNodeData for the data property of the custom nodes. It specifies the structure for the node's label and its source/target handle definitions.
package.json: This file lists the project's dependencies. Key dependencies include:
@xyflow/svelte: The core library for the flow diagram.@gradio/atoms, @gradio/icons, @gradio/statustracker, @gradio/utils: Components and utilities from the Gradio ecosystem, used for building the UI consistently with other Gradio components.The component is designed to be a custom Gradio component.
value prop. The component watches for changes to this prop and updates the SvelteFlow diagram accordingly.change event to the Gradio backend with the updated nodes and edges. select and submit events are also dispatched on the respective user actions. This allows the Python backend to react to user interactions in real-time.{
"nodes": [
{
"id": "node-1",
"type": "dynamic",
"position": {"x": 100, "y": 150},
"data": {
"label": "Start",
"sources": [{"id": "node-1-s1"}],
"targets": [{"id": "node-1-t1"}],
"topOffsetPx": 0, # Optional
"sideOffsetPx": 8, # Optional
},
},
{
"id": "node-2",
"type": "dynamic",
"position": {"x": 250, "y": 150},
"data": {
"label": "Process A",
"sources": [{"id": "node-2-s1"}],
"targets": [{"id": "node-2-t1"}],
"topOffsetPx": 0, # Optional
"sideOffsetPx": 8, # Optional
},
}
]
}
{
"edges": [
{
"id": "e1-2",
"source": "node-1",
"target": "node-2"
"sourceHandle": "node-1-s1",
"targetHandle": "node-2-t1"
}
]
}
[] Undo/redo: Since we already track lastDispatched, layering a simple history stack would be straightforward.