Skip to content

Models ​

Node ​

A graph node with generic user data, position, and interaction properties.

swift
public struct Node<NodeData: Equatable & Sendable>: Identifiable, Equatable, Sendable

Properties ​

PropertyTypeDefaultDescription
idString—Unique identifier (required)
positionXYPosition—Position on canvas (required)
dataNodeData—User-defined data (required)
typeString"default"Node type for styling and filtering
parentIdString?nilParent node ID for grouping and sub-flows
selectedBoolfalseWhether the node is currently selected
hiddenBoolfalseWhether the node is hidden
widthCGFloat?nilExplicit width; nil = measured from content
heightCGFloat?nilExplicit height; nil = measured from content
draggableBooltrueWhether the node can be dragged
selectableBooltrueWhether the node can be selected
connectableBooltrueWhether handles on this node accept connections
deletableBooltrueWhether the node can be deleted (keyboard or deleteElements)
expandableBoolfalseWhether the node can expand/collapse sub-nodes
expandedBooltrueCurrent expanded state (if expandable)
expandParentBoolfalseGrow the parent while dragging this child past its edges
focusableBooltrueWhether the node can receive keyboard focus (Tab)
zIndexInt0Render order (higher = on top)
originNodeOrigin.topLeftAnchor point: node top-left = position - origin * size. Wins over the canvas nodeOrigin when not .topLeft. Child positions are relative to the parent's top-left
sourcePositionPosition?nilSide edges attach to when the node has no rendered source handle (default right)
targetPositionPosition?nilSide edges attach to when the node has no rendered target handle (default left)
extentNodeExtent?nilDrag constraint (.parent or .coordinateExtent)
styleNodeStyle?nilPer-node visual style applied by the canvas (background, border, radius, opacity)

Initialization ​

swift
let node = Node(
    id: "node-1",
    position: XYPosition(x: 100, y: 200),
    data: "My Node Data",
    type: "custom",
    selected: false,
    draggable: true,
    selectable: true,
    connectable: true
)

Codable Support ​

Node becomes Codable when NodeData conforms to Codable. This enables full graph serialization.


Edge ​

A connection between two nodes with visual style, labels, markers, and animation.

swift
public struct Edge<EdgeData: Equatable & Sendable & Hashable>: Identifiable, Equatable, Sendable, Hashable

Properties ​

PropertyTypeDefaultDescription
idString—Unique identifier (required)
sourceString—Source node ID (required)
targetString—Target node ID (required)
sourceHandleString?nilSource handle ID (for multi-handle nodes)
targetHandleString?nilTarget handle ID (for multi-handle nodes)
typeEdgeType.defaultPath style
selectedBoolfalseSelection state
hiddenBoolfalseVisibility
labelString?nilText label displayed at edge midpoint
animatedBoolfalseAnimated dash pattern
markerStartEdgeMarker?nilStart endpoint marker
markerEndEdgeMarker?nilEnd endpoint marker
zIndexInt0Render order
reconnectableBoolfalseWhether endpoints can be dragged to reconnect (also requires onReconnect, selection and nodesConnectable)
deletableBooltrueDeletable via keyboard or deleteElements
focusableBooltrueWhether the edge can receive keyboard focus (Tab)
interactionWidthCGFloat20Width of the invisible hit area used for selection and clicks
dataEdgeData?nilUser-defined data
styleEdgeStyle?nilPer-edge visual style overrides (stroke color, width, opacity)

EdgeType ​

ValueDescription
.default / .bezierSmooth cubic bezier curve
.straightDirect straight line
.stepRight-angle path with sharp corners
.smoothstepRight-angle path with rounded corners
.simplebezierCubic curve with control points at the axis midpoint

EdgeMarker ​

swift
public struct EdgeMarker: Equatable, Sendable, Codable, Hashable {
    var type: MarkerType   // .arrow or .arrowClosed
    var width: CGFloat     // default: 12
    var height: CGFloat    // default: 12

    static let arrow       // Open arrowhead
    static let arrowClosed // Filled arrowhead
}

MarkerType ​

ValueDescription
.arrowOpen arrowhead (stroke only)
.arrowClosedFilled arrowhead (triangle)

Creating Edges ​

swift
// Basic edge
let edge = FlowEdge<EmptyEdgeData>(id: "e1", source: "1", target: "2")

// Styled edge with arrowhead and label
let edge = FlowEdge<EmptyEdgeData>(
    id: "e1-2",
    source: "1", target: "2",
    sourceHandle: "out", targetHandle: "in",
    type: .smoothstep,
    label: "flows to",
    animated: true,
    markerEnd: EdgeMarker(type: .arrowClosed)
)

// Edge with custom data
struct FlowData: Equatable, Sendable, Codable, Hashable {
    var weight: Double
}
let edge = Edge<FlowData>(
    id: "e1", source: "1", target: "2",
    data: FlowData(weight: 1.0)
)

EmptyEdgeData ​

Use EmptyEdgeData when edges don't need custom data:

swift
@State var edges: [FlowEdge<EmptyEdgeData>] = [
    FlowEdge(id: "e1", source: "1", target: "2")
]

FlowEdge Type Alias ​

When SwiftFlow and SwiftUI share the same namespace, use FlowEdge:

swift
let edges: [FlowEdge<EmptyEdgeData>] = [...]

Codable Support ​

Edge becomes Codable when EdgeData conforms to Codable.


Connection ​

Represents a pending connection request between two handles.

swift
public struct Connection: Equatable, Sendable, Codable, Hashable {
    var source: String        // Source node ID
    var target: String        // Target node ID
    var sourceHandle: String? // Source handle ID
    var targetHandle: String? // Target handle ID
}

Passed to onConnect and isValidConnection callbacks during interactive edge drawing.


Viewport ​

Camera state describing pan offset and zoom level.

swift
public struct Viewport: Equatable, Sendable, Codable, Hashable {
    var x: CGFloat       // Horizontal pan offset
    var y: CGFloat       // Vertical pan offset
    var zoom: CGFloat    // Zoom level (0.1 ... 4.0)

    static let identity  // x: 0, y: 0, zoom: 1.0
    static let minZoom: CGFloat = 0.1
    static let maxZoom: CGFloat = 4.0
}

XYPosition ​

A 2D coordinate on the canvas.

swift
public struct XYPosition: Equatable, Sendable, Codable, Hashable {
    var x: CGFloat
    var y: CGFloat

    static let zero  // (0, 0)

    // Arithmetic operators
    static func + (lhs:, rhs:) -> XYPosition
    static func - (lhs:, rhs:) -> XYPosition

    // Grid snapping
    func snapped(to grid: (x: CGFloat, y: CGFloat)) -> XYPosition
}

SwiftUI-native node graph editor.