# @pyreon/flow

Reactive flow diagrams for Pyreon. Signal-native nodes, edges, pan/zoom, and auto-layout via elkjs. No D3 dependency.

## Install

```bash
bun add @pyreon/flow
```

## Quick Start

```tsx
import { createFlow, Flow, Background, MiniMap, Controls } from '@pyreon/flow'

const flow = createFlow({
  nodes: [
    { id: '1', position: { x: 0, y: 0 }, data: { label: 'Start' } },
    { id: '2', position: { x: 200, y: 100 }, data: { label: 'End' } },
  ],
  edges: [{ source: '1', target: '2' }],
})

<Flow instance={flow}>
  <Background />
  <MiniMap />
  <Controls />
</Flow>
```

## API

### `createFlow(config)`

Create a reactive flow instance with signal-based state.

### `useFlow(config)`

Component-scoped wrapper around `createFlow` — auto-disposes the instance when the component unmounts. Prefer this inside component bodies; use `createFlow` directly only for flows owned outside the component tree (app stores, singletons).

```tsx
const MyDiagram = () => {
  const flow = useFlow({
    nodes: [{ id: '1', position: { x: 0, y: 0 }, data: { label: 'Start' } }],
    edges: [],
  })
  return <Flow instance={flow}><Background /></Flow>
}
```

**Reactive state:** `flow.nodes`, `flow.edges`, `flow.viewport`

**Node operations:** `addNode()`, `removeNode()`, `updateNode()`, `updateNodePosition()`

**Edge operations:** `addEdge()`, `removeEdge()`

**Selection:** `selectNode()`, `selectEdge()`, `clearSelection()`, `deleteSelected()`

**Viewport:** `zoomIn()`, `zoomOut()`, `zoomTo()`, `fitView()`, `panTo()`

**Layout:** `flow.layout(algorithm, options)` — auto-layout via elkjs (lazy-loaded). Algorithms: `layered`, `force`, `stress`, `tree`, `radial`, `box`, `rectpacking`.

> **Algorithm-specific options**: `direction`, `layerSpacing`, and `edgeRouting` are namespaced under ELK's layered/tree pipelines and are silently ignored by `force`, `stress`, `radial`, `box`, and `rectpacking`. `nodeSpacing` is the only `LayoutOptions` field respected by every algorithm. See [`docs/docs/flow.md`](../../../docs/docs/flow.md#auto-layout) for the full applicability table.

**Graph queries:** `getConnectedEdges()`, `getIncomers()`, `getOutgoers()`, `isValidConnection()`

**Listeners:** `onConnect()`, `onNodesChange()`, `onNodeClick()`, `onEdgeClick()`

### Components

| Component       | Description                                                      |
| --------------- | ---------------------------------------------------------------- |
| `<Flow>`        | Main container with pan/zoom via pointer events + CSS transforms |
| `<Background>`  | Dot or line grid background                                      |
| `<MiniMap>`     | Overview minimap                                                 |
| `<Controls>`    | Zoom/fit buttons                                                 |
| `<Handle>`      | Connection handle on nodes                                       |
| `<Panel>`       | Overlay panel positioned relative to the flow                    |
| `<NodeResizer>` | Resize handle for nodes                                          |
| `<NodeToolbar>` | Toolbar attached to a node                                       |

### Edge Paths

`getBezierPath()`, `getSmoothStepPath()`, `getStraightPath()`, `getStepPath()`, `getWaypointPath()`

### `Position`

Enum: `Top`, `Right`, `Bottom`, `Left`

## License

MIT
