Foblex Flow v18.6.0 is the layout-interaction sequel to v18.5.0. The previous release made layout engines a first-class story for the initial render. This one makes layouts stay clean as the graph keeps changing, and gives you control over how the canvas itself is stacked.
Today I'm shipping v18.6.0 with two features: Reflow on Resize and Layer Ordering.
Highlights
- 🧭
withReflowOnResize— one-line install, reacts to any node size change, no manual relayout call. - 🎛️ Five orthogonal reflow knobs — mode, scope, axis, delta source, and collision. Each one controls one decision and stays out of the way of the others.
- 📌
fReflowIgnoredirective — pin annotations, legends, and stats panels so they never receive a primary shift. - ⚙️
FReflowController— change any reflow option at runtime without re-providing the plugin. - 🔁 Standard
(fMoveNodes)pipeline — shifted positions go through your normal application write path. - 🗂️
[fLayers]input — per-canvas control over the order of groups, connections, and nodes. - 🧩
withFCanvas({ layers })provider — set the same canvas layer order once for every canvas in the host component's tree. - 🛡️ Default layer order unchanged — groups → connections → nodes stays the default, so existing apps are unaffected.
Reflow on Resize
Real graphs do not have static node sizes.
A node expands when its details panel opens. It shrinks when async data finishes loading. It grows when the user types a longer label. As soon as one node changes size, every other node nearby is suddenly in the wrong place — overlapping, blocking the path of an edge, breaking the carefully arranged columns.
withReflowOnResize watches every node in the canvas and, the moment a size changes, shifts surrounding nodes so the layout stays clean. No manual relayout, no graph rebuild — the consumer model just receives the new positions through the standard (fMoveNodes) pipeline.
Installation is one line:
import { provideFFlow, withReflowOnResize } from '@foblex/flow';
@Component({
providers: [provideFFlow(withReflowOnResize())],
})
export class MyFlow {}That is the whole installation. No directives to attach, no events to subscribe to.
Mode and Scope: Who Moves, How Far
The behaviour is configurable because "shift nearby nodes" is too vague for real layouts. The planner combines a mode, a scope, an axis, a delta source, and a collision resolver. Each knob picks one decision and stays out of the way of the others.
mode decides which nodes are eligible to shift when the source resizes:
CENTER_OF_MASS(default) — every node whose centre lies past the source's centre on the resize axis. No connection or column alignment required.X_RANGE— same idea, narrowed to nodes that overlap the source on the perpendicular axis. Useful for column-based layouts where a vertical resize should only push the same column.DOWNSTREAM_CONNECTIONS— only nodes reachable from the source via outgoing connections. Pipeline-style editors rely on this so a resize doesn't disturb unrelated branches.
scope decides how far the plan is allowed to look:
GLOBAL(default) — every node and group on the canvas is eligible.GROUP— restricted to the source's siblings. Use it when each group should behave like an isolated workspace.CONNECTED_SUBGRAPH— BFS from the source over connections in both directions. Disconnected islands stay still.
When a shifting candidate would overlap a stationary node, collision decides who gives way: STOP clamps at the spacing line, while CHAIN_PUSH absorbs the anchor into the plan and pushes it too.
For nodes that should always stay pinned regardless of what the rest of the graph does — annotations, legend labels, stats panels — use fReflowIgnore:
<div fNode fReflowIgnore [fNodePosition]="legendPosition">
Legend
</div>Every knob can also be changed at runtime through FReflowController.
Layer Ordering
Foblex Flow renders three built-in layers inside <f-canvas> — groups, connections, and nodes — each in its own absolutely-positioned container with its own stacking context. Until v18.6.0 the order was hardcoded: groups underneath, connections in the middle, nodes on top.
That default has been right for the vast majority of editors for years, and it stays the default in v18.6.0. But some editors need a different stack:
- A diagram view with semi-transparent group overlays needs the group layer above the nodes so the tint is visible.
- A pipeline editor with clickable edge labels needs connections above nodes so labels stay reachable when nodes overlap them.
- A custom render layer that draws on top of connections needs the connection container drawn last so its strokes are not occluded.
Two equivalent entry points are available:
<!-- Per-canvas: groups, nodes, connections — connections drawn on top -->
<f-canvas [fLayers]="[EFCanvasLayer.GROUPS, EFCanvasLayer.NODES, EFCanvasLayer.CONNECTIONS]">
<!-- ... -->
</f-canvas>import { provideFFlow, withFCanvas, EFCanvasLayer } from '@foblex/flow';
@Component({
providers: [
provideFFlow(
withFCanvas({
layers: [EFCanvasLayer.GROUPS, EFCanvasLayer.NODES, EFCanvasLayer.CONNECTIONS],
}),
),
],
})
export class MyEditor {}Per-canvas [fLayers] always wins over the app-wide value. Missing layers fall back to their default position, and unknown values or duplicates are silently dropped.
Breaking Change
- virtualization: removed the unused
fVirtualForTrackByinput on*fVirtualFor. The input was declared but never wired into the rendering path, so providing atrackByfunction had no effect. Drop the expression from affected templates:*fVirtualFor="let item of items(); trackBy trackFn;"→*fVirtualFor="let item of items();".
Release Links
- Changelog: https://github.com/Foblex/f-flow/blob/main/CHANGELOG.md
- Release article: https://flow.foblex.com/blog/foblex-flow-v18-6-0-smart-auto-layout-on-resize
- Reflow on Resize example: https://flow.foblex.com/examples/reflow-on-resize
- Canvas Layer Ordering example: https://flow.foblex.com/examples/canvas-layers
- Roadmap: https://flow.foblex.com/docs/roadmap
Closing
The two features in v18.6.0 sit at different layers of the library, but they share a theme: making the canvas behave the way real editors actually need it to behave, without forcing application code to fight the library.
Reflow on Resize is about ongoing editing: when nodes change size, when content streams in, when a card toggles open. Layer Ordering is about the canvas's own visual contract: the default stacking stays unchanged, but editors that need a different order now get a configuration call instead of a !important z-index war.
If you're building a visual editor in Angular and want a native Angular solution — not a React wrapper — take a look. And if you like what I'm building, please consider starring the repo ⭐