# BlowCanvas (Component) `Bit.Blow.BlowCanvas` - inherits `ComponentBase` - implements `IAsyncDisposable`, `IBlowContext`, `IComponent`, `IHandleAfterRender`, `IHandleEvent` The flow canvas: a pannable, zoomable surface that renders a graph of nodes and edges and owns every interaction with it - dragging, selecting, connecting, resizing and the keyboard. Give it a BlowCanvas.Nodes list (and usually an BlowCanvas.Edges one) and it renders them; it mutates those lists in place as the user edits and raises BlowCanvas.NodesChanged and BlowCanvas.EdgesChanged so a caller can persist the result. Overlays - BlowBackground, BlowControls, BlowMiniMap, BlowPanel - go in BlowCanvas.ChildContent; node and edge appearance is replaced with BlowCanvas.NodeTemplate and BlowCanvas.EdgeTemplate. Capture it with @ref for the imperative API: BlowCanvas.FitView, BlowCanvas.SetViewport, BlowCanvas.ToObject, the clipboard and so on. It is the Blazor counterpart of React Flow's plus useReactFlow(). ## Parameter - **AdditionalAttributes** : `IReadOnlyDictionary` - Any additional attributes (id, data-*, aria-*, ...) are splatted onto the flow's root element, so the canvas can be wired into surrounding markup without wrapping it. - **AllowSelfConnections** : `bool` = `false` - When true a node may connect to itself (through two different handles). Off by default, matching the intuition that a node shouldn't loop back on itself unless asked for. - **AriaLabel** : `string` = `"Flow diagram"` - Accessible name for the flow region. Announced by screen readers. - **AriaLabels** : `BlowAriaLabels` = `BlowAriaLabels.Default` - The strings the flow announces and labels itself with. Replace it to localize the flow or to reword the announcements; see BlowAriaLabels for the defaults. - **AttributionPosition** : `BlowPanelPosition` = `BlowPanelPosition.BottomRight` - Corner the attribution badge is anchored to. Defaults to bottom-right. - **AutoPanMargin** : `double` = `30` - Distance in screen pixels from the pane border at which auto-panning kicks in. - **AutoPanOnConnect** : `bool` = `true` - Same as BlowCanvas.AutoPanOnNodeDrag, for dragging a connection. - **AutoPanOnNodeDrag** : `bool` = `true` - When true, dragging a node past the edge of the pane scrolls the viewport to follow, so nodes can be moved beyond the currently visible area. - **AutoPanOnNodeFocus** : `bool` = `true` - When true, tabbing to a node that is off screen pans the viewport to bring it into view. Without this a keyboard user can move focus into a node they cannot see, which is the point at which tab navigation stops being usable. Mirrors React Flow's autoPanOnNodeFocus. - **AutoPanOnNodeFocusDuration** : `int` = `200` - Milliseconds the viewport takes to travel when BlowCanvas.AutoPanOnNodeFocus brings a focused node into view. Zero jumps straight there. - **AutoPanSpeed** : `double` = `15` - Screen pixels the viewport travels per auto-pan step. - **ChildContent** : `RenderFragment` - Overlay content: place BlowBackground, BlowControls, BlowMiniMap, BlowPanel here. - **Class** : `string` - Additional CSS class(es) for the flow root element. - **ClipboardShortcutsEnabled** : `bool` = `false` - Enables Ctrl/Cmd+C, X, V and D for copy, cut, paste and duplicate, using the canvas's own clipboard. Off by default: a flow embedded in a page whose surrounding UI already handles those keys should not quietly take them over. - **ColorMode** : `BlowColorMode` = `BlowColorMode.Light` - Color theme applied to the flow. - **ConnectionDragThreshold** : `double` = `1` - Pointer travel in screen pixels before the in-progress connection line is drawn. Keeps a click on a handle from flashing a line. Mirrors React Flow's connectionDragThreshold. - **ConnectionLineClass** : `string` - Extra CSS class(es) for the default in-progress connection line. - **ConnectionLineStyle** : `string` - Inline style applied to the default in-progress connection line, e.g. "stroke:#f6ab6c;stroke-width:3;stroke-dasharray:5 5". Ignored when BlowCanvas.ConnectionLineTemplate draws the line instead. - **ConnectionLineTemplate** : `RenderFragment` - Optional custom renderer for the line drawn while creating a connection. Receives the live BlowConnectionLineContext; render SVG. When null, a default path is drawn. - **ConnectionLineType** : `BlowEdgeType` = `BlowEdgeType.Bezier` - Path style used for the in-progress connection line while dragging. - **ConnectionMode** : `BlowConnectionMode` = `BlowConnectionMode.Strict` - Controls which handle pairings are valid when connecting (Strict vs Loose). - **ConnectionRadius** : `double` = `20` - Radius in screen pixels around the pointer within which a released connection snaps to the nearest valid handle. Set to 0 to require releasing exactly on a handle. - **ConnectOnClick** : `bool` = `false` - When true, connections are made by clicking a source handle and then clicking a target handle, instead of (or in addition to) dragging. - **DefaultEdgeOptions** : `BlowDefaultEdgeOptions` - Default values applied to edges created by user interaction. - **DefaultEdgeType** : `BlowEdgeType` = `BlowEdgeType.Bezier` - Path type given to edges the user creates, unless BlowDefaultEdgeOptions overrides it. - **DefaultMarkerColor** : `string` - Arrowhead colour used by edges that do not name one of their own. When null (the default) an arrowhead takes its edge's stroke colour. Mirrors React Flow's defaultMarkerColor. - **DefaultViewport** : `BlowViewport?` - Initial viewport for an uncontrolled flow, applied on first render. Ignored when BlowCanvas.Viewport is set (which controls the viewport outright) or when BlowCanvas.FitViewOnInit wins by fitting the graph instead. - **DeleteKeyEnabled** : `bool` = `true` - Enables the DeleteKeys shortcut for removing the selection. - **DeleteKeys** : `IReadOnlyList` = `["Delete", "Backspace"]` - The keys that delete the selection. Mirrors React Flow's deleteKeyCode; set it to just Delete when Backspace should always mean "go back" instead. Ignored when BlowCanvas.DeleteKeyEnabled is false. - **DisableKeyboardA11y** : `bool` = `false` - Disables keyboard interactions (node focus + arrow-key movement) when true. - **EdgeLabelTemplate** : `RenderFragment` - Optional HTML renderer for edge labels, drawn in a non-transformed overlay so labels stay a constant screen size (React Flow's EdgeLabelRenderer). Positioned at the edge's label point. When set, it is used instead of the built-in SVG label. - **Edges** : `List` = `[]` - The edges to render. - **EdgesChanged** : `EventCallback>` - Raised after the canvas has changed the edge list, for persistence or two-way binding. - **EdgesFocusable** : `bool` = `true` - When false, edges are skipped by Tab navigation. - **EdgesReconnectable** : `bool` = `true` - Globally enables dragging existing edge endpoints to new handles. - **EdgeTemplate** : `RenderFragment` - Optional custom renderer for edges. Receives an BlowEdgeContext with the computed geometry and endpoints; render SVG (path, labels, etc.). Switch on context.Edge.Type or custom data inside. When null, the built-in edge is drawn. - **ElementsSelectable** : `bool` = `true` - Globally enables selecting nodes and edges. Individual elements can still opt out. - **ElevateEdgesOnSelect** : `bool` = `false` - Raises an edge above its peers while it is selected. - **ElevateNodesOnSelect** : `bool` = `true` - Raises a node above its peers while it is selected or dragged. - **FitViewOnInit** : `bool` = `false` - When true, the graph is fitted to the pane once, after the first measurement that finds something to fit - so a graph loaded after the canvas first rendered is still fitted. - **FitViewOptions** : `BlowFitViewOptions` - Options used by the initial BlowCanvas.FitViewOnInit fit. Ignored when BlowCanvas.FitViewOnInit is false. - **GuideColor** : `string` = `"#f43f5e"` - Colour of the alignment guides. Defaults to a magenta that is conventional for the feature and unlikely to be confused with the graph itself. - **GuideDistance** : `double` = `6` - How close, in screen pixels, a dragged node has to come before it snaps to a guide. Measured on screen rather than in flow units so the feel stays the same at any zoom. - **HideAttribution** : `bool` = `false` - Hides the small "bit Blow" attribution badge when true. - **HistoryCapacity** : `int` = `100` - How many undo steps the built-in history keeps; values below one keep one. Ignored when BlowCanvas.HistoryEnabled is false. - **HistoryEnabled** : `bool` = `false` - Turns on undo/redo, driven by the canvas itself: it records a step at each point a user would recognise as one - a drag finished, an edge connected or reconnected, something deleted, pasted, resized, aligned or nudged - and binds Ctrl/Cmd+Z and Ctrl/Cmd+Shift+Z (or Ctrl+Y) to move through them. Off by default, for the same two reasons the clipboard shortcuts are: a flow embedded in a page whose surrounding UI already owns those keys should not quietly take them, and an app that already has its own undo stack wants its edits in that one, not in a second one the canvas keeps privately. Driving BlowHistory yourself from the change callbacks remains fully supported and is the right answer for that case. - **IsValidConnection** : `Func` - Optional predicate to validate a prospective connection while the user drags. Return false to reject; rejected targets are highlighted differently. - **MaxZoom** : `double` = `2.5` - Largest zoom factor the viewport may reach. - **MinZoom** : `double` = `0.2` - Smallest zoom factor the viewport may reach. - **MultiSelectionKey** : `BlowModifierKey` = `BlowModifierKey.Shift` - Which modifier key adds to the current selection (multi-select). Defaults to Shift. - **NodeClickDistance** : `double` = `3` - How far the pointer may travel during a node gesture and still count as a click. Beyond this, BlowCanvas.OnNodeClick is suppressed on release. - **NodeDragThreshold** : `double` = `1` - Minimum pointer travel in screen pixels before a node drag begins. Until this distance is exceeded the gesture is treated as a click (so the node selects but does not move). Mirrors React Flow's nodeDragThreshold. - **NodeExtent** : `BlowRect?` - Optional flow-space rectangle that constrains where root nodes can be dragged. - **NodeOrigin** : `BlowXYPosition` = `BlowXYPosition.Zero` - Default origin (0,0 = top-left, 0.5,0.5 = center) defining which point of a node its Position refers to. Individual nodes can override via BlowNode.Origin. - **Nodes** : `List` = `[]` **(required)** - The nodes to render. Mutated in place during drag/select. - **NodesChanged** : `EventCallback>` - Raised after the canvas has changed the node list, for persistence or two-way binding. - **NodesConnectable** : `bool` = `true` - Globally enables starting/accepting connections. Individual nodes can still opt out. - **NodesDraggable** : `bool` = `true` - Globally enables dragging nodes. Individual nodes can still opt out. - **NodesFocusable** : `bool` = `true` - When false, nodes are skipped by Tab navigation. - **NodeTemplate** : `RenderFragment` - Optional custom renderer for node content. Switch on node.Type inside. - **NoDragClass** : `string` = `"nodrag"` - CSS class marking an element inside a node that must not start a drag - the standard escape hatch for inputs, sliders and buttons living inside custom nodes. Mirrors React Flow's noDragClassName. Set to null to disable the guard. - **NoPanClass** : `string` = `"nopan"` - CSS class marking an element that must not pan the viewport when dragged. Mirrors React Flow's noPanClassName. Set to null to disable the guard. - **NoWheelClass** : `string` = `"nowheel"` - CSS class marking an element that keeps its own wheel events - so a scrollable panel inside the flow scrolls instead of zooming the canvas. Mirrors React Flow's noWheelClassName. Set to null to disable the guard. - **OnBeforeDelete** : `Func, IReadOnlyList, bool>` - Optional veto for deletions. Receives the nodes and edges about to be deleted; return false to cancel the deletion. Mirrors React Flow's onBeforeDelete. - **OnConnect** : `EventCallback` - Raised when the user completes a connection, with the wiring that was created. - **OnConnectEnd** : `EventCallback` - Raised when a connection drag ends, whether it produced an edge or not. The payload carries the final flow/screen position and whether the drop landed on a valid handle, enabling interactions like adding a node where the connection was released. - **OnConnectionChange** : `EventCallback` - Raised on connection start, on each pointer move while connecting, and once with null when the connection ends. Mirrors React Flow's useConnection updates. - **OnConnectStart** : `EventCallback` - Raised when the user begins dragging a connection from a handle. - **OnDelete** : `EventCallback` - Raised after any deletion with the removed nodes and edges. - **OnEdgeClick** : `EventCallback` - Raised when an edge is clicked. - **OnEdgeContextMenu** : `EventCallback` - Raised when an edge is right-clicked. The browser menu is suppressed. - **OnEdgeDoubleClick** : `EventCallback` - Raised when an edge is double-clicked. - **OnEdgeMouseEnter** : `EventCallback` - Raised when the pointer enters an edge. - **OnEdgeMouseLeave** : `EventCallback` - Raised when the pointer leaves an edge. - **OnEdgeMouseMove** : `EventCallback` - Raised as the pointer moves over an edge. Only listened for when a handler is supplied. - **OnEdgesDelete** : `EventCallback>` - Raised with the edges that were just deleted. - **OnError** : `EventCallback` - Raised when the flow notices something wrong with the graph it was handed - a duplicate node id, an edge pointing at a node that isn't there. Each distinct problem is reported once rather than on every render. - **OnHistoryChanged** : `EventCallback` - Raised whenever the built-in history changes - a step recorded, or one undone or redone. The usual use is enabling and disabling undo/redo buttons. - **OnInit** : `EventCallback` - Raised once after the flow is first rendered and measured; receives the canvas for imperative use. - **OnlyRenderVisibleElements** : `bool` = `false` - When true, only nodes/edges intersecting the current viewport (plus a margin) are rendered. Improves performance on large graphs. Unmeasured nodes are always rendered once so they can be sized. - **OnMove** : `EventCallback` - Raised continuously while the viewport is panned or zoomed. - **OnMoveEnd** : `EventCallback` - Raised when a pan/zoom gesture ends. - **OnMoveStart** : `EventCallback` - Raised when the user starts panning or zooming the viewport. - **OnNodeClick** : `EventCallback` - Raised when a node is clicked. A drag that travelled past NodeClickDistance is not a click. - **OnNodeContextMenu** : `EventCallback` - Raised when a node is right-clicked. The browser menu is suppressed. - **OnNodeDoubleClick** : `EventCallback` - Raised when a node is double-clicked. - **OnNodeDrag** : `EventCallback` - Raised on every pointer move while a node is dragged. - **OnNodeDragStart** : `EventCallback` - Raised when a node drag begins, with the node the pointer grabbed. - **OnNodeDragStop** : `EventCallback` - Raised when a node drag ends. The usual place to capture an undo step. - **OnNodeMouseEnter** : `EventCallback` - Raised when the pointer enters a node. - **OnNodeMouseLeave** : `EventCallback` - Raised when the pointer leaves a node. - **OnNodeMouseMove** : `EventCallback` - Raised as the pointer moves over a node. Only listened for when a handler is supplied. - **OnNodeResize** : `EventCallback` - Raised on every pointer move during a node resize. - **OnNodeResizeEnd** : `EventCallback` - Raised when a node resize gesture ends. - **OnNodeResizeStart** : `EventCallback` - Raised when a node resize gesture starts. - **OnNodesDelete** : `EventCallback>` - Raised with the nodes that were just deleted. - **OnNodesInitialized** : `EventCallback` - Raised once every node has been measured, and again whenever that becomes true after a node was added. Layout algorithms need real node sizes, so this is the cue to run one. - **OnPaneClick** : `EventCallback` - Raised when the empty pane is clicked. A drag that panned the viewport is not a click. - **OnPaneContextMenu** : `EventCallback` - Raised when the empty pane is right-clicked. - **OnPaneMouseEnter** : `EventCallback` - Raised when the pointer enters the pane. - **OnPaneMouseLeave** : `EventCallback` - Raised when the pointer leaves the pane. - **OnPaneMouseMove** : `EventCallback` - Raised as the pointer moves over the pane. Only listened for when a handler is supplied. - **OnPaneScroll** : `EventCallback` - Raised for every wheel event over the pane, before pan/zoom handling. - **OnPaste** : `EventCallback` - Raised after elements are pasted, with the fragment that was added. - **OnReconnect** : `EventCallback` - Raised when an existing edge is reconnected to a new handle. - **OnReconnectEnd** : `EventCallback` - Raised when a reconnect gesture finishes, whether or not it rewired the edge. A common use is deleting the edge when it was dropped on empty space. - **OnReconnectStart** : `EventCallback` - Raised when the user grabs one end of an existing edge to reconnect it. - **OnSelectionChange** : `EventCallback` - Raised whenever the set of selected nodes/edges changes. - **OnSelectionContextMenu** : `EventCallback` - Raised when a node that is part of a multi-node selection is right-clicked, carrying the whole selection. The usual use is a context menu that acts on everything selected rather than only on the node under the cursor. - **OnSelectionDrag** : `EventCallback` - Raised on every pointer move while a multi-node selection is being dragged. - **OnSelectionDragStart** : `EventCallback` - Raised when a drag begins that moves more than one node, with everything that is moving. Nudging a single node raises only BlowCanvas.OnNodeDragStart; moving a marquee selection raises both, so a listener can treat the group as one edit. - **OnSelectionDragStop** : `EventCallback` - Raised when a multi-node drag ends. - **OnSelectionEnd** : `EventCallback` - Raised when a selection-box gesture ends. - **OnSelectionStart** : `EventCallback` - Raised when the user begins drawing a selection box on the pane. - **OnViewportChanged** : `EventCallback` - Raised when a pan or zoom settles, with the resulting viewport. - **PanActivationKey** : `string` = `" "` - Key that, while held, turns a left-drag anywhere on the pane into a pan even when BlowCanvas.SelectionOnDrag is on. Set to null to disable. Defaults to the space bar. - **PanButtons** : `IReadOnlyList` = `[0]` - Mouse buttons that pan the viewport when dragged on the pane: 0 = left, 1 = middle, 2 = right. Defaults to left only. Middle-button panning is a common addition for flows that use left-drag for box selection. - **PaneClickDistance** : `double` = `3` - How far the pointer may travel during a pane gesture and still count as a click. Beyond this, BlowCanvas.OnPaneClick is suppressed on release. - **PanOnDrag** : `bool` = `true` - When true, dragging the pane background pans the viewport. - **PanOnScroll** : `bool` = `false` - When true, mouse-wheel/trackpad scrolling pans the viewport; pinch (Ctrl+wheel) still zooms. - **PanOnScrollMode** : `BlowPanOnScrollMode` = `BlowPanOnScrollMode.Free` - Restricts pan-on-scroll to a single axis when set. - **PanOnScrollSpeed** : `double` = `0.5` - Pan speed multiplier applied to wheel deltas when BlowCanvas.PanOnScroll is enabled. - **PasteOffset** : `BlowXYPosition` = `(24, 24)` - How far a paste is offset from what it was copied from, so the copy is visible rather than sitting exactly on top of the original. - **PreventDuplicateEdges** : `bool` = `true` - When true, a connection whose source/target/handles exactly match an existing edge is rejected instead of creating a duplicate. Mirrors addEdge's behaviour. - **PreventScrolling** : `bool` = `true` - When true (the default) wheel events over the flow are consumed so the page behind it doesn't scroll. Set to false to let the page scroll normally. A wheel the flow does not act on - a plain scroll while BlowCanvas.ZoomActivationKey is not held, or while BlowCanvas.ZoomOnScroll is off - always reaches the page. - **ReconnectRadius** : `double` = `10` - Radius in screen pixels of the grab area around a selected edge's endpoints. The visible dot stays small; this is how close the pointer has to come to pick the endpoint up. Mirrors React Flow's reconnectRadius. - **SelectAllKeyEnabled** : `bool` = `true` - Enables Ctrl/Cmd+A to select every selectable element. - **SelectEdgesOnSelectionBox** : `bool` = `true` - When true, box selection also picks up edges whose two endpoints are both selected, so dragging a box round a cluster selects the sub-graph rather than only its nodes. - **SelectionKey** : `BlowModifierKey?` = `BlowModifierKey.Shift` - Key that, while held, turns a pane drag into a box selection. Defaults to Shift, matching React Flow's selectionKeyCode. Set to null to require BlowCanvas.SelectionOnDrag. - **SelectionMode** : `BlowSelectionMode` = `BlowSelectionMode.Partial` - How box selection decides membership: Partial (any overlap) or Full (fully enclosed). - **SelectionOnDrag** : `bool` = `false` - When true, dragging on the pane background draws a selection box instead of panning. Box selection is also available while BlowCanvas.SelectionKey is held, regardless of this setting. - **SelectNodesOnDrag** : `bool` = `true` - When true (the default), pressing a node selects it immediately. Turn it off to make a plain drag move the node without changing the selection, so a marquee selection survives nudging one of its members. - **SnapGridX** : `double` = `15` - Horizontal grid step (flow units) used when BlowCanvas.SnapToGrid is enabled. - **SnapGridY** : `double` = `15` - Vertical grid step (flow units) used when BlowCanvas.SnapToGrid is enabled. - **SnapToGrid** : `bool` = `false` - When true, dragged node positions snap to BlowCanvas.SnapGridX/BlowCanvas.SnapGridY. - **SnapToGuides** : `bool` = `false` - When true, a dragged node clicks into alignment with the nodes around it - edges and centres - and a thin guide line shows what it lined up with. This is the "smart guides" behaviour of a drawing tool, and it takes precedence over BlowCanvas.SnapToGrid on whichever axis actually found an alignment. - **Style** : `string` - Inline style for the flow root element. Give it a height: the canvas fills its container. - **TranslateExtent** : `BlowRect?` - Optional flow-space rectangle that constrains how far the viewport can be panned. - **Viewport** : `BlowViewport?` - Optional controlled viewport. When set, the flow adopts the value whenever it changes; pair it with BlowCanvas.OnViewportChanged to drive pan/zoom entirely from your own state. Leave null (the default) for an uncontrolled viewport. - **ZIndexMode** : `BlowZIndexMode` = `BlowZIndexMode.Auto` - How much of the stacking order the canvas manages. BlowZIndexMode.Manual hands it back to you entirely, ignoring BlowCanvas.ElevateNodesOnSelect and BlowCanvas.ElevateEdgesOnSelect. - **ZoomActivationKey** : `BlowModifierKey?` - Key that must be held for the wheel to zoom. Null (the default) means the wheel zooms unconditionally; set it to make plain scrolling pass through to the page. Mirrors React Flow's zoomActivationKeyCode. - **ZoomOnDoubleClick** : `bool` = `true` - When true, double-clicking the pane zooms in (Shift+double-click zooms out). - **ZoomOnPinch** : `bool` = `true` - When true, a two-finger pinch on the pane zooms the viewport about the midpoint between the fingers. This is the only way to zoom on a touch device, so it defaults to on. - **ZoomOnScroll** : `bool` = `true` - When true, the mouse wheel zooms the viewport (unless PanOnScroll takes it over). ## Property - **CanPaste** : `bool` = `false` - True when there is something to paste. - **CanRedo** : `bool` = `false` - True when the built-in history has a state to go forward to. - **CanUndo** : `bool` = `false` - True when the built-in history has an earlier state to go back to. - **CurrentNodes** : `IReadOnlyList` = `[]` - The live node list, exposed to overlays such as the minimap. - **History** : `BlowHistory` - The canvas's own history, or null unless BlowCanvas.HistoryEnabled is set. Exposed so a toolbar can read its depth, and so an app can capture a step of its own at a moment the canvas has no way to know about. - **IsConnecting** : `bool` = `false` - True while the user is drawing a connection from a handle. - **NodesInitialized** : `bool` = `false` - True once every visible node has been measured. Layout algorithms need real sizes, so this is the signal that the graph is ready to be arranged. - **PaneSize** : `BlowDimensions` = `BlowDimensions.Empty` - The pane's measured size in screen pixels, or BlowDimensions.Empty before the first measurement. ## Method - **AddEdges**(BlowEdge[] edges) : `void` - Appends edges. - **AddNodes**(BlowNode[] nodes) : `void` - Appends nodes and triggers a re-measure. - **AlignSelectionAsync**(BlowAlignEdge edge) : `Task` - Lines the selected nodes up on one edge or axis - the align buttons of a drawing tool. Does nothing when fewer than two selected nodes can be moved. Positions are parent-relative, so a selection spanning several parents is aligned within each parent's own space. Selecting siblings is the case this is meant for. - **Announce**(string message) : `void` - Publishes a message to the flow's aria-live region for screen readers. A live region is only re-read when its text changes, so announcing the same thing twice in a row (nudging a node twice with the same arrow key, say) would be silent the second time. Alternating an invisible zero-width space makes the text differ without changing a single spoken word. - **BeginNodeDrag**(BlowNode node, PointerEventArgs e) : `void` - Starts dragging a node, bypassing the custom-drag-handle restriction. Called by BlowDragHandle. - **CaptureHistory**() : `void` - Records the current graph as an undo step. Does nothing when the built-in history is off, or when the graph is identical to the step already recorded - so it is safe to call from anywhere an edit might have happened without checking first. - **CapturePointer**(ElementReference element, long pointerId) : `void` - Captures a pointer on an element so a drag started there survives leaving it. - **CompleteConnection**(string nodeId, string handleId, BlowHandleType handleType) : `void` - Completes the in-progress connection on the given handle, if it is a valid target. - **Copy**() : `BlowFragment` - Copies the current selection into the flow's clipboard and returns it. Every edge running between two selected nodes comes along, whether or not the edge itself was selected: copying three nodes and getting back three unconnected ones is not what anyone means by copying part of a graph. An edge with one end outside the selection is left behind, since there would be nothing for it to connect to. - **CutAsync**() : `Task` - Copies the current selection, then deletes it. - **DeleteElementsAsync**(IEnumerable nodes = null, IEnumerable edges = null) : `Task` - Removes the given nodes (and their connected edges) and/or edges. - **DescribeConnection**(string nodeId, string handleId, BlowHandleType handleType) : `BlowConnection` - Describes the connection completing on the given handle would produce, normalised so Source always refers to the source-side handle. - **DisposeAsync**() : `ValueTask` - **DistributeSelectionAsync**(bool horizontal, double? gap = null) : `Task` - Spaces the selected nodes evenly across the span they already occupy. - **DuplicateSelectionAsync**() : `Task` - Copies the selection and pastes it in one step, leaving the clipboard untouched - the Ctrl+D that every editor has, and which should not cost you what you had copied. - **FitBounds**(BlowRect bounds, double padding = 0.1) : `void` - Pans/zooms so the given flow-space rectangle fills the pane. - **FitBoundsAsync**(BlowRect bounds, double padding, int durationMs) : `Task` - Eases the viewport so the given flow-space rectangle fills the pane. - **FitView**() : `void` - Pans and zooms so the whole graph fits the pane, with a 10% margin. - **FitView**(double padding) : `void` - Pans and zooms so the whole graph fits the pane. - **FitView**(BlowFitViewOptions options) : `void` - Pans/zooms so the requested nodes fill the pane. Mirrors React Flow's fitView, including its options for padding, hidden nodes, a zoom range and a node subset. - **FitViewAsync**(BlowFitViewOptions options) : `Task` - Fits the view, easing there over BlowFitViewOptions.Duration milliseconds instead of jumping. Mirrors React Flow's fitView({ duration }). - **FitViewAsync**(int durationMs) : `Task` - Fits the whole graph, easing there over durationMs milliseconds. - **FlowToScreenPosition**(BlowXYPosition flow) : `BlowXYPosition` - Converts a flow-space point to a screen-space (client) point. - **GetEdge**(string id) : `BlowEdge` - Returns the edge with the given id, or null. - **GetHandleConnections**(string nodeId, BlowHandleType type, string handleId) : `IReadOnlyList` - Returns the connections attached to one specific handle. - **GetIntersectingNodes**(BlowRect area, bool partially = true) : `IReadOnlyList` - Returns the nodes overlapping the given flow-space rectangle. - **GetIntersectingNodes**(BlowNode node, bool partially = true) : `IReadOnlyList` - Returns the nodes overlapping the given node's bounds (excluding itself). - **GetNode**(string id) : `BlowNode` - Returns the node with the given id, or null. - **GetNodeConnections**(string nodeId, BlowHandleType? type = null, string handleId = null) : `IReadOnlyList` - Returns the connections attached to a node, optionally filtered to one handle type and/or handle id. Mirrors React Flow's getNodeConnections. - **GetViewport**() : `BlowViewport` - The current viewport pan/zoom transform. - **GetZoom**() : `double` - The current zoom factor. - **IsConnectionSource**(string nodeId, string handleId, BlowHandleType handleType) : `bool` - True when the in-progress connection started from this exact handle, so it can be shown as the origin of the drag rather than as a rejected target. - **IsNodeIntersecting**(BlowNode node, BlowRect area, bool partially = true) : `bool` - True when the node overlaps (or is fully within) the given area. - **IsValidConnectionTarget**(string nodeId, string handleId, BlowHandleType handleType) : `bool` - True when the in-progress connection could legally complete on the given handle. - **OnResizeObserved**(bool measureNodes = true) : `Task` - Called from JS when the pane or any node changes size. Nothing in C# can observe this, yet both the pane rectangle (screen <-> flow conversions, minimap mask) and the node measurements (edge anchors, fit-view bounds) depend on it. - **PasteAsync**() : `Task` - Adds a fresh copy of the flow's clipboard to the graph, selected and offset so it is visible. Returns what was added, or an empty fragment when there was nothing to paste. - **PasteAsync**(BlowFragment fragment, BlowXYPosition? offset = null) : `Task` - Adds a fresh copy of the given fragment to the graph. - **RedoAsync**() : `Task` - Goes forward one step. Returns false when nothing had been undone. - **Refresh**(bool remeasure) : `void` - Re-renders the canvas, optionally re-measuring node sizes and handle anchors first. - **RegisterHandle**(string key, BlowHandleRegistration registration) : `void` - Registers a handle's validation predicate and connect callback. Used by BlowHandle. - **RegisterViewportPortal**(object key, RenderFragment fragment) : `void` - Registers content to render inside the transformed viewport layer. Used by BlowViewportPortal. - **RestoreAsync**(BlowSnapshot snapshot, bool restoreViewport = true, bool detach = true) : `Task` - Replaces the current graph and viewport with a saved snapshot, in place - the bound BlowCanvas.Nodes and BlowCanvas.Edges lists keep their identity, so a caller holding a reference to either still sees the restored graph. - **ScreenToFlowPosition**(double clientX, double clientY) : `BlowXYPosition` - Converts a screen-space (client) point to flow coordinates. - **SelectAllAsync**() : `Task` - Selects every selectable, visible node and edge. Mirrors a Ctrl+A style select-all. - **SetCenter**(double x, double y, double? zoom = null) : `void` - Centers the viewport on the given flow point, optionally setting the zoom. - **SetCenterAsync**(double x, double y, double? zoom, int durationMs) : `Task` - Eases the viewport to centre on the given flow point. - **SetConnectionHover**(string nodeId, string handleId, BlowHandleType handleType, bool isOver) : `void` - Tells the canvas the pointer has entered or left a handle while connecting. - **SetViewport**(BlowViewport viewport) : `void` - Applies a viewport, clamping zoom to Min/Max and honouring BlowCanvas.TranslateExtent. - **SetViewportAsync**(BlowViewport viewport, int durationMs) : `Task` - Eases the viewport to viewport over durationMs milliseconds. Mirrors the duration option React Flow's viewport helpers take: a jump cut between two parts of a large graph loses the reader, where a short transition keeps them oriented. A duration of zero applies the viewport immediately. - **StartConnection**(string nodeId, string handleId, BlowHandleType handleType, BlowPosition position) : `void` - Begins a connection drag from the given handle. Called by BlowHandle. - **StartConnection**(string nodeId, string handleId, BlowHandleType handleType, BlowPosition position, long pointerId) : `void` - Begins a connection drag from the given handle, capturing the pointer on the pane so the gesture survives the pointer leaving the flow. - **StartConnection**(string nodeId, string handleId, BlowHandleType handleType, BlowPosition position, long pointerId, double clientX, double clientY) : `void` - Begins a connection drag, additionally telling the canvas where on screen the gesture started so BlowCanvas.ConnectionDragThreshold has a real origin to measure from. - **StartResize**(string nodeId, BlowResizeDirection direction, double clientX, double clientY, double minWidth, double minHeight, bool keepAspectRatio) : `void` - Begins a node resize gesture. Called by BlowNodeResizer and BlowNodeResizeControl. - **StartResize**(string nodeId, BlowResizeDirection direction, double clientX, double clientY, double minWidth, double minHeight, bool keepAspectRatio, double maxWidth, double maxHeight, long pointerId) : `void` - Begins a node resize gesture with size bounds, capturing the pointer on the pane so the gesture survives the pointer leaving the flow. - **ToObject**(bool deep = true) : `BlowSnapshot` - Returns a snapshot of the current nodes, edges and viewport. By default the nodes and edges are cloned, so the snapshot keeps describing the flow as it was even as the user carries on editing. Pass deep: false to get the live instances instead. - **UndoAsync**() : `Task` - Goes back one step. Returns false when there was nothing to go back to. - **UnregisterHandle**(string key) : `void` - Removes a previously registered handle. - **UnregisterHandle**(string key, BlowHandleRegistration registration) : `void` - Removes a handle's registration only while it is still the one held for the key. - **UnregisterViewportPortal**(object key) : `void` - Removes previously registered viewport-portal content. - **UpdateNodeInternals**(string[] nodeIds) : `void` - Re-measures node sizes and handle anchors. Call it after changing a node's handles - adding one, moving one to another side - since nothing about that is visible to C#. Mirrors React Flow's useUpdateNodeInternals. Measuring is a single pass over the whole flow, so naming particular nodes does not make it cheaper; the ids are accepted because that is how the intent reads at the call site. - **ZoomIn**() : `void` - Zooms in one step about the pane centre. - **ZoomOut**() : `void` - Zooms out one step about the pane centre. - **ZoomTo**(double zoom) : `void` - Sets the absolute zoom level, keeping the pane center stationary. - **ZoomToAsync**(double zoom, int durationMs) : `Task` - Eases to the given zoom level over durationMs milliseconds.