Connection admission
Loading interactive example…Open in new tab ↗
Connect the sender to the listener using the toolbar or ports. The quiet node rejects connections. Rejected ports turn red; releasing cancels the connection. Denied verbs show a reason and leave history unchanged. Try undo and redo on an accepted connection.
First, Run checks in the review panel. The missing-route finding selects both nodes when clicked. Create the connection, then run checks again to clear it. Undo restores the incomplete draft; another check finds the missing route again. Draft diagnostics are explicit and do not prevent editing. Admission rules reject invalid connections immediately. See domain diagnostics.
The example uses one endpoint rule at two complementary boundaries:
| API | Responsibility |
|---|---|
DiagramRules(canConnect: ...) | Evaluate hover, preview, creation and reconnection intent. targetIsStart preserves direction when moving the source endpoint. |
DiagramRules(beforeChange: (p) => validate(p.after)) | Enforce the same invariant on every candidate document, including imports and history. It does not run on the controller's initial document. |
A port hover without an opposite endpoint is allowed until a pair can be checked. This example requires bound endpoints, so a rejected target cannot leave a free connection behind. Application permissions belong in the same beforeChange rule.
The validator scans connections in this small fixture. It demonstrates admission semantics, not a large-document performance policy or remote authorization.
See Controller and Rules and changes.
Source
dart
EditResult admitExampleEndpoints(
ConnectorEndpoint? start,
ConnectorEndpoint? end,
) =>
start is BoundEndpoint &&
start.elementId == 'sender' &&
start.portId == 'right' &&
end is BoundEndpoint &&
end.elementId == 'listener' &&
end.portId == 'left'
? const EditResult.allow()
: const EditResult.denied(reason: 'Only sender → listener is allowed.');