Grow a node with its ports, stop it flickering, draw what it reaches out to
- A node's height follows the ports on its busiest side. It is a function of the document, so `layoutGraph` reserves exactly what is drawn and nothing measured is fed back into the layout. - The three status controls now sit in slots that are there whether the control is or not. A node running many times a second mounted and unmounted the stop button on every execution, resizing the card each time. - A port bound to another flow's message is drawn as a label, naming the node at the far end and its type. Only the opposite direction was answered before. The scan behind both is now cached on the store's commit counter rather than reading every flow per request. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016ZeGnqVsf5VHQqvz4HdUhN
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* A node's height against the ports it has to fit.
|
||||
*
|
||||
* Run: `bun src/components/Flow/layout.check.ts` (there is no unit runner; the
|
||||
* suite in `tests/` drives a running stack). Typechecked with the rest of
|
||||
* `src` and imported by nothing, so it is not in the bundle.
|
||||
*/
|
||||
import assert from "node:assert/strict"
|
||||
|
||||
import { layoutGraph, nodeHeight, PORT_SPAN } from "./layout"
|
||||
|
||||
/** Handles are 12px across — see `.react-flow__handle` in `flow.css`. */
|
||||
const HANDLE = 12
|
||||
|
||||
// Two ports fit the plain box, so most nodes are unchanged.
|
||||
assert.equal(nodeHeight(0), 56)
|
||||
assert.equal(nodeHeight(1), 56)
|
||||
assert.equal(nodeHeight(2), 56)
|
||||
assert.ok(nodeHeight(3) > 56)
|
||||
|
||||
for (let ports = 2; ports <= 12; ports += 1) {
|
||||
const height = nodeHeight(ports)
|
||||
// `handleOffset` spreads the ports over `PORT_SPAN` of the edge, so that is
|
||||
// the room they actually get. Two handles must not touch.
|
||||
const between = (PORT_SPAN * height) / (ports - 1)
|
||||
assert.ok(
|
||||
between > HANDLE,
|
||||
`${ports} ports on a ${height}px node leave ${between}px between handles`,
|
||||
)
|
||||
// Growing, never shrinking: one more port can only need more room.
|
||||
assert.ok(height >= nodeHeight(ports - 1))
|
||||
}
|
||||
|
||||
// The layout places top-left corners, so a taller node has to be lifted by its
|
||||
// own half-height rather than by the default box's.
|
||||
const tall = nodeHeight(8)
|
||||
const placed = layoutGraph(
|
||||
["a", "b"],
|
||||
[{ source: "a", target: "b" }],
|
||||
"LR",
|
||||
new Map([["b", tall]]),
|
||||
)
|
||||
const a = placed.get("a")
|
||||
const b = placed.get("b")
|
||||
assert.ok(a && b)
|
||||
// Dagre centres the two on one rank line, so the taller one starts higher up
|
||||
// by exactly the difference in half-heights.
|
||||
assert.equal(Math.round(a.y - b.y), Math.round((tall - 56) / 2))
|
||||
|
||||
console.log("layout: ok")
|
||||
Reference in New Issue
Block a user