# EdgeSpec

Import it from `@grafloria/renderer`.

An edge, as a host hands it in. Node-to-node, like React Flow.

Both
fields live on `LinkModel`, both round-trip through `serialize()`… and neither
was on `EdgeSpec`. So the A* / manhattan obstacle routers, and every custom
connector, were addressable only by reaching past the spec layer into the live
model. Same for `metadata`, which is how a link names its anchor and its
connection-point strategy (floating edges), and for `points`, which is how a
host restores saved waypoints.

```ts
interface EdgeSpec
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `id?` | `string` |  |  |
| `source` | `string` |  | Source NODE id (a port id also resolves, for full control). |
| `target` | `string` |  | Target NODE id. |
| `sourceHandle?` | `string` |  | Port id, or a bare side name (`'right'`). Naming a handle PINS the edge to that port. When neither handle is named the edge is PORT-FACING: it attaches to the node's real port on whichever side faces its partner (the `'port-facing'` strategy), so a layouted tree connects bottom→top instead of looping out of a frozen right→left pick — and the endpoint always sits on a port, never sliding along the … |
| `targetHandle?` | `string` |  | Port id, a bare side name (`'left'`), or a side AT a point along it: `'left@36'` (36 px down the left side), `'bottom@138'` (138 px from the bottom's left end), `'right@50%'`. See `sourceHandle` for the default. |
| `type?` | `'direct' \| 'smooth' \| 'orthogonal' \| 'bezier'` |  |  |
| `router?` | `LinkRouterName` |  | WHERE the line goes: `straight` \| `orthogonal` \| `manhattan` \| `avoid` \| `elk`, or any router registered on the RoutingEngine. Unset = derived from `type`. |
| `connector?` | `LinkConnectorName` |  | HOW the polyline is drawn: `straight` \| `rounded` \| `smooth` \| `bezier`, or any name passed to `registerConnector`. Unset = derived from `type`. |
| `label?` | `string` |  |  |
| `labelPlacement?` | `'on' \| 'above' \| 'below'` |  | Where the label sits: `'on'` the line on its own little box (the default), or `'above'` / `'below'` it with no box — the labels of the diagrams AI tools draw. Decided against the line's direction where the label lands, so on a vertical run `'above'` means to its left. |
| `labelStyle?` | `LabelStyle` |  | The label's own colour, size, weight, family, background (`'none'` for no box). |
| `waypoints?` | `Point[]` |  | The bends the line must take, in world coordinates — interior points only; its ends stay on their ports. Drawn as MANUAL waypoints (the user's own bends), so the router keeps them: "M580,264 V204 H850 V154" is `waypoints: [{ x: 580, y: 204 }, { x: 850, y: 204 }]`. |
| `style?` | `Partial<LinkStyle>` |  |  |
| `selected?` | `boolean` |  |  |
| `data?` | `Record<string, any>` |  |  |
| `metadata?` | `Record<string, any>` |  | Link metadata. This is how a link names its `sourceAnchor` / `targetAnchor` and its `connectionPoint` strategy — i.e. how floating edges are turned on per link. |
| `points?` | `Point[]` |  | Explicit waypoints. Restores a user-edited route. |
