Skip to content

Release Notes

Version 0.5.1

A small enhancement release that lets the canvas accept files dragged in from the operating system.

Enhancements

  • Drop files onto the canvas: add "Files" to drop_types to accept files dragged in from the operating system. The drop event's data lists each file's name, type, size and text content, so a handler can, for example, load a graph saved as JSON. See React to Events (#79).

Version 0.5.0

This release adds port and edge value inspection, connection checks and canvas drops for interactive graph editing. Node and Edge properties now sync to the browser in place, batches of changes render as a single update, and an error boundary keeps a malformed graph from blanking the canvas.

Highlights

  • Port and edge inspection: handle and edge click events can open a Panel popup with flow.show_popup(content, position). Set popup_trigger="hover" to use hover events instead; use flow.close_popup() to dismiss it. Applications supply the value to display, and examples/port_value_inspection.py shows both interactions (#74).

  • Connection validation: opt-in browser policies reject connections with the wrong direction or handle type, full inputs, duplicate edges, and cycles. Register Python rules with add_connection_validator() to show rejection reasons on candidate handles during a drag. Python validators check interactive drags only; they do not restrict flow.add_edge() or direct changes to flow.edges. See Validate Connections and examples/connection_validation.py (#75).

  • Error recovery: the canvas is now wrapped in an error boundary, controlled by the new error_recovery parameter ("auto" by default, or "manual" / "off"). In "auto" mode a React render error remounts the canvas, then remounts again in a view-only safe mode that repairs or hides elements it cannot render (invalid positions, unknown node/edge types, dangling edges, duplicate or missing ids) without mutating the server-side graph. If retries are exhausted a recovery panel offers Try again, Reload page and Copy details. Every error is logged to the panel.reactflow logger and emitted as a client_error event, so browser-side failures are no longer invisible to the server (#70).

  • Base property sync: the top-level React Flow fields on Node and Edge (label, type, style, className, draggable, connectable, deletable, ...) are now synced to the frontend, so assigning node.label = "Start (running)" patches the browser in place instead of requiring flow.nodes to be replaced. Parameters declared on a subclass continue to sync into data. New patch_node_props() and patch_edge_props() methods do the same for dict-based nodes and edges, where passing None clears a field back to the CSS/theme default, and new on_props_change hooks fire on Node/Edge subclasses when the frontend changes a property. position and selected remain browser-owned during drag and selection and are only pushed via patch_node_props() (#71).

Enhancements

  • Batch removal: remove_node() and remove_edge() now accept several ids, either as separate arguments (flow.remove_node("n1", "n2")) or as a sequence (flow.remove_node(["n1", "n2"])), and remove them in a single update. For any other batch of changes made from Python, wrap them in pn.io.hold() to render them at once (#72).

  • Drop data onto the canvas: drop_types lists MIME types the canvas accepts, and each drop of one of them emits a drop event with the dropped data, its flow position, and the node or handle under the pointer, so a handler can add and wire what was dropped. Draggable panel_material_ui.MenuList items work as a source; see React to Events (#77).

Bug fixes

  • Nodes remounted when node types change: any change to node_types rebuilt the component for every node type, so React remounted every node and detached its embedded view, which could leave Bokeh plots blank. Each type's component is now reused until its own spec or the popup settings change (#77).

  • Progressive re-render when deleting multiple elements: deleting a multi-node selection removed the nodes one at a time, syncing an intermediate graph to the browser per node so the nodes visibly disappeared one by one. Updates triggered by a frontend message are now held and combined into a single patch, and node/edge deletion assigns nodes and edges once (#72).

  • Serialization error when updating node_types: assigning NodeType or EdgeType descriptors with a schema class after construction synced them to the browser before they were converted to JSON descriptors, so the server failed with can't serialize ParameterizedMetaclass. They are now converted before syncing, and updating node_types and edge_types together no longer raises a TypeError (#76).

Version 0.4.1

A small enhancement release adding viewport zoom controls.

Enhancements

  • Zoom limits — new min_zoom (default 0.5) and max_zoom (default 2) parameters constrain how far the canvas can be zoomed out and in, and can be updated at runtime (#69).

Version 0.4.0

This release adds new interaction features, edge routing options, and handle customization capabilities.

Highlights

  • Right-click context menu — nodes and the canvas now support a configurable context menu triggered on right-click, enabling custom actions like delete, duplicate, or copy without toolbar buttons (#65).
  • Smart edge routing — new smart edge types (smartBezier, smartStep, smartStraight) that automatically route around nodes instead of passing through them (#64).
  • Handle connectivity controls — per-type flags (input_connectable, input_connectable_start, input_connectable_end, and their output_* counterparts) let you restrict which handles users can drag edges from or to (#63).
  • Handle tooltips — handles can now carry a label that appears as an instant tooltip on hover, making port purpose discoverable without cluttering the canvas. Pass {"id": "port_name", "label": "Description"} in your inputs/outputs lists (#67).
  • Node.flow and Edge.flow back-references — instance-based nodes and edges now hold a .flow reference to their parent ReactFlow, simplifying imperative graph manipulation from callbacks (#56).
  • Delete key support — selected nodes and edges can now be removed with the Delete key, matching standard graph-editor UX expectations.
  • Bundle cache-busting — the frontend bundle URL now includes a content hash, preventing stale cached bundles after upgrades (#68).

Bug fixes

  • Fixed stale node views not updating and deletion causing flicker (#60).
  • Fixed flow attribute initialization on component creation (#59).
  • Edge/node add/remove events are now emitted exactly once (#58).
  • Fixed removing a node when edges are defined as Edge instances (#57).

Version 0.3.0

This release focuses on core graph-model capabilities, callback ergonomics, rendering/styling improvements, and major documentation expansion.

Highlights

  • Parameterized Node/Edge instances as first-class graph elements — ReactFlow now supports instance-based graph authoring with richer Python object workflows, including improved serialization/sync behavior and expanded API/core test coverage.
  • Event callback improvements — .on(...) callbacks can now accept the ReactFlow instance as a second argument and support async callbacks, making app-level event handling significantly more flexible.
  • Rendering fixes for embedded views — improved scaling and interaction behavior when rendering figures inside nodes, including better handling of drag/pan/scroll conflicts within embedded content.
  • Editor rendering robustness — fixed node and edge editor rendering paths so editors can render reliably even when no node view is defined.
  • Color mode and default node styling support — added color-mode-aware styling capabilities and refined baseline node CSS for better defaults out of the box.
  • Expanded how-to documentation — substantial updates to guides for declaring types, defining nodes/edges, editors, embedding views, reacting to events, and styling, with refreshed screenshots across the docs.
  • Examples overhaul in docs — added an examples gallery with grid cards and dedicated pages/screenshots for each example app, plus docs navigation updates for easier discovery.

Version 0.2.0

This release focuses on stronger typed graph specs, better node-view handling, and improved docs and packaging.

Highlights

  • NodeSpec view support — added a view parameter to NodeSpec and fixed add_node behavior so embedded views are preserved when adding nodes programmatically.
  • Safer embedded view handling — fixed an AttributeError when node views are Panel Viewer objects or other arbitrary view-like objects.
  • EdgeSpec handle targeting — added sourceHandle and targetHandle fields to support explicit edge-to-port connections.
  • Spec auto-serialization — added automatic serialization for NodeSpec and EdgeSpec objects to reduce boilerplate when using dataclass-based graph definitions.
  • Handle rendering fix — corrected empty handle list behavior so [] is treated distinctly from missing/undefined handles.
  • Styling hook for labels — added the rf-node-label CSS class on node labels for easier targeted styling.
  • Docs and onboarding updates — quickstart and index docs now explicitly document the required pn.extension("jsoneditor") setup; additional how-to docs were updated for new handle and serialization behavior.
  • Packaging reliability — ensured the frontend dist assets are included in distributions.

Version 0.1.0

Initial release

Panel-ReactFlow brings the power of React Flow to the Panel ecosystem, giving Python developers a fully interactive node-based graph editor with minimal boilerplate.

Highlights

  • ReactFlow component — a Panel component that renders an interactive React Flow canvas with drag, select, connect, and delete support.
  • Python-first graph state — define nodes and edges as plain Python dictionaries; all changes sync bidirectionally between the frontend and Python.
  • Node & edge types — use NodeType and EdgeType dataclasses to declare typed nodes and edges with optional JSON Schema for their data payloads.
  • Schema-driven editors — auto-generate editing forms from JSON Schema (via SchemaEditor) or fall back to a raw JSON tree view (JsonEditor). Custom editors can be any Python callable or class.
  • Editor display modes — show editors inline inside nodes (editor_mode="node"), in a toolbar popover ("toolbar"), or in a side panel ("side").
  • Embedded views — pass any Panel Viewable as a node's view to render rich content (charts, indicators, widgets) directly inside graph nodes.
  • Event system — subscribe to granular events (node_added, edge_deleted, selection_changed, …) or use "*" to listen to everything.
  • Custom handles — configure named input and output ports per node type.
  • Stylesheets — apply CSS stylesheets targeting .react-flow__node-{type} and .react-flow__edge-{type} classes for full visual control.
  • Panel integration — top_panel, bottom_panel, left_panel, and right_panel slots for surrounding the canvas with arbitrary Panel components.
  • Helper dataclasses — NodeSpec and EdgeSpec for validated node/edge construction; convenience methods add_node, remove_node, add_edge, remove_edge, and patch_node_data / patch_edge_data for live graph manipulation.