Summary
Flow is a great fit for linear/parallel workflow diagrams, but its node and connector rendering are tightly coupled, which blocks a class of "labelled ladder" diagrams: sequences where each connector carries semantic meaning (colour/direction) and where the diagram should wrap rather than pan. Today the only escape hatch is to abandon Flow entirely and hand-roll connectors.
This issue proposes three related enhancements so Flow can cover these cases natively.
Motivating use case
We have a "tier ladder" in an internal admin tool: the rate plans in a product family shown left-to-right as an upgrade/downgrade path. The connectors are the information, not just decoration:
- Green connector: the path from the lowest tier up to the account's currently-active tier ("already traversed").
- Red, reversed connector: a downgrade candidate.
- Neutral connector: everything else.
The ladder also lives in a dense, narrow column, so it wraps into rows of three with a "continues below" down-connector, rather than panning horizontally.
We evaluated migrating this to Flow and could not, for the reasons below.
Current limitations (v2.6.0)
-
Connectors are owned entirely by <Flow> and expose no per-connector styling. Connector geometry is computed in FlowDiagram from registered node rects; the only per-node knob that reaches a connector is disabled (greys it). There is no supported way to say "the connector arriving at / leaving this node is red" or "this connector points the other way". (See packages/kumo/src/components/flow/.)
-
Flow.Node cannot be used outside <Flow>. Flow.Node calls useDescendantsContext, which throws useDescendantsContext must be used within DescendantsProvider when there is no <Flow> ancestor. So consumers cannot reuse just the node presentation while composing their own connectors.
-
Layout is single-line + pan only; no wrapping mode. When a horizontal diagram overflows its container it pans. There is no row-wrapping layout for dense/narrow containers.
The net effect: Flow is all-or-nothing. If you need any per-connector semantics or a wrapping layout, you must drop Flow and reimplement connectors by hand, losing the component's measurement/anchor machinery.
Proposed enhancements
Any one of these would help; ideally 1 + 3.
-
Per-connector styling API. For example, a connector prop on Flow.Node (styling the incoming edge) or a renderConnector/connectorVariant prop on Flow / Flow.Parallel:
<Flow>
<Flow.Node>Tier 1</Flow.Node>
<Flow.Node connector={{ variant: 'success' }}>Tier 2 (active)</Flow.Node>
<Flow.Node connector={{ variant: 'danger', direction: 'reverse' }}>Tier 3 (downgrade)</Flow.Node>
</Flow>
A small set of semantic variants (default | success | danger | muted) that map to Kumo tokens would cover most cases; a render prop would cover the rest.
-
Wrapping layout mode. An opt-in layout="wrap" (or wrap / columns) on Flow that flows nodes into rows when they exceed the container width, with connectors drawn per-row and an inter-row indicator, as an alternative to canvas panning.
-
Standalone Flow.Node presentation. Let Flow.Node render its styled body when there is no DescendantsProvider (no-op the connector registration) instead of throwing, so the node's look-and-feel can be reused while a consumer composes connectors themselves. This decouples node presentation from the connector engine.
Why native support is preferable
Hand-rolling connectors means reimplementing getBoundingClientRect tracking, ResizeObserver, scroll/resize remeasurement, and anchor bookkeeping that Flow already does well. Exposing a thin styling/layout seam would let these semantic-ladder diagrams stay on Flow and benefit from that machinery.
Happy to help prototype the connector-styling seam if the direction sounds reasonable.
Summary
Flowis a great fit for linear/parallel workflow diagrams, but its node and connector rendering are tightly coupled, which blocks a class of "labelled ladder" diagrams: sequences where each connector carries semantic meaning (colour/direction) and where the diagram should wrap rather than pan. Today the only escape hatch is to abandonFlowentirely and hand-roll connectors.This issue proposes three related enhancements so
Flowcan cover these cases natively.Motivating use case
We have a "tier ladder" in an internal admin tool: the rate plans in a product family shown left-to-right as an upgrade/downgrade path. The connectors are the information, not just decoration:
The ladder also lives in a dense, narrow column, so it wraps into rows of three with a "continues below" down-connector, rather than panning horizontally.
We evaluated migrating this to
Flowand could not, for the reasons below.Current limitations (v2.6.0)
Connectors are owned entirely by
<Flow>and expose no per-connector styling. Connector geometry is computed inFlowDiagramfrom registered node rects; the only per-node knob that reaches a connector isdisabled(greys it). There is no supported way to say "the connector arriving at / leaving this node is red" or "this connector points the other way". (Seepackages/kumo/src/components/flow/.)Flow.Nodecannot be used outside<Flow>.Flow.NodecallsuseDescendantsContext, which throwsuseDescendantsContext must be used within DescendantsProviderwhen there is no<Flow>ancestor. So consumers cannot reuse just the node presentation while composing their own connectors.Layout is single-line + pan only; no wrapping mode. When a horizontal diagram overflows its container it pans. There is no row-wrapping layout for dense/narrow containers.
The net effect:
Flowis all-or-nothing. If you need any per-connector semantics or a wrapping layout, you must dropFlowand reimplement connectors by hand, losing the component's measurement/anchor machinery.Proposed enhancements
Any one of these would help; ideally 1 + 3.
Per-connector styling API. For example, a
connectorprop onFlow.Node(styling the incoming edge) or arenderConnector/connectorVariantprop onFlow/Flow.Parallel:A small set of semantic variants (
default | success | danger | muted) that map to Kumo tokens would cover most cases; a render prop would cover the rest.Wrapping layout mode. An opt-in
layout="wrap"(orwrap/columns) onFlowthat flows nodes into rows when they exceed the container width, with connectors drawn per-row and an inter-row indicator, as an alternative tocanvaspanning.Standalone
Flow.Nodepresentation. LetFlow.Noderender its styled body when there is noDescendantsProvider(no-op the connector registration) instead of throwing, so the node's look-and-feel can be reused while a consumer composes connectors themselves. This decouples node presentation from the connector engine.Why native support is preferable
Hand-rolling connectors means reimplementing
getBoundingClientRecttracking,ResizeObserver, scroll/resize remeasurement, and anchor bookkeeping thatFlowalready does well. Exposing a thin styling/layout seam would let these semantic-ladder diagrams stay onFlowand benefit from that machinery.Happy to help prototype the connector-styling seam if the direction sounds reasonable.