Flow: per-connector styling, wrapping layout, and standalone Flow.Node
- Dominant language
- TypeScript
- Stars
- 3.9k
- Forks
- 177
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 48
Description
## 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)
1. **Connectors are owned entirely by `` 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/`.)
2. **`Flow.Node` cannot be used outside ``.** `Flow.Node` calls `useDescendantsContext`, which throws `useDescendantsContext must be used within DescendantsProvider` when there is no `` ancestor. So consumers cannot reuse just the node presentation while composing their own connectors.
3. **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.
1. **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`:
```tsx
Tier 1
Tier 2 (active)
Tier 3 (downgrade)
```
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.
2. **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.
3. **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.
Contributor guide
Research direction
Start in packages/kumo/src/components/flow/ and read FlowDiagram, Flow.Node, and useDescendantsContext to understand node registration and connector geometry. First choose and scope one of the three proposed enhancements; done means the selected behavior and API work without breaking existing Flow usage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- design, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100