Foblex Flow
Introduction
Overview
Nodes
Custom Nodes
Drag Handle
Node Selection
Resize Handle
Rotate Handle
Grouping
Drag to Group
Connectors
Node as Connector
Connector Inside Node
Connector Outlet
Limiting Connections
Connection Rules
Connectable Side
Updated
Connections - Editing
Drag to Connect
Drag to Reassign
Create Node on Connection Drop
Remove Connection on Drop
Assign Node to Connection on Drop
Auto Snap
Connections - Appearance
Connection Types (Straight, Segment, Bezier, Adaptive Curve)
Custom Connection Type
Connection Behaviours
Connection Markers
Connection Content
Updated
Connection Gradients
Updated
Connections - Routing
Connection Waypoints
New
Connection Connectable Side
New
Viewport
Minimap
Zoom
Background
Auto Pan
New
Canvas Layer Ordering
New
Editor Helpers
Selection Area
Magnetic Lines
New
Magnetic Rects
New
Grid System
Add Node from Palette
Help in Positioning (Legacy)
Deprecated
Layout Engines
Dagre Layout
New
Dagre Auto Layout
New
ELK.js Layout
New
ELK.js Auto Layout
New
Reflow
Reflow on Resize
New
Editor State
Cut/Copy/Paste
Undo/Redo
Undo/Redo V2
Events
Drag Start/End Events
Custom Event Triggers
Performance
Large Scene Performance
Connection Redraw Performance
Updated
Reference Apps
AI Low-Code Platform
Updated
Schema Designer
Updated
Call Center Flow
Updated
UML Diagram
Updated
Tournament Bracket
Updated
Foblex Flow

Reflow on Resize

Real graphs don't have static node sizes. A node expands when its details panel opens, shrinks when async data loads, 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 is the plugin that fixes this. It watches every node in the canvas and, the moment a size changes, shifts the surrounding nodes so the layout stays clean. No manual relayout call, no graph rebuild — the consumer model just receives the new positions through the standard (fMoveNodes) pipeline.

The plugin reacts to any size change. User-driven resize handles work too, but they aren't the point — they're the easiest way to demonstrate each option on this page.

The behaviour is configurable. A planner combines a mode, a scope, an axis, a delta source, and a collision resolver — five orthogonal knobs that decide who moves, by how much, and what to do when shifts run out of room. Each section below picks one knob, locks the rest at sensible defaults, and shows you the difference.

Installation

That is the whole installation. No directives to attach, no events to subscribe to.

Basics

The simplest case — and the one the plugin was designed for. Three nodes, no resize handles. The source grows when its inner block toggles open. The plugin notices and shifts the nodes underneath. Replace the toggle with any real-world driver — a collapsible card, lazy-loaded payload, dynamic text — and the behaviour is the same.

[example.html] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/basics/example.html [example.ts] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/basics/example.ts [example.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/basics/example.scss

The remaining sections wire a resize handle onto the source so you can poke each option deliberately. The plugin reacts the same way regardless of what changes the size.

Mode — who becomes a candidate

mode decides which nodes are eligible to shift when the source resizes. The scene has a connected chain leaving the source (Source → Connected → Connected) and two unconnected nodes nearby. Drag any handle on the source and switch the dropdown:

  • CENTER_OF_MASS (default) — picks every node whose centre lies past the source's centre on the resize axis. Nothing else is required: no connection, no parent, no column alignment.
  • X_RANGE — same idea, narrowed to nodes that overlap the source on the perpendicular axis. Useful when the layout is column-based and a vertical resize should only push the same column.
  • DOWNSTREAM_CONNECTIONS — only nodes reachable from the source via outgoing connections. The chain follows; unconnected nodes stay put. Pipeline-style editors rely on this so a resize doesn't disturb unrelated branches.

[example.html] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/mode/example.html [example.ts] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/mode/example.ts [example.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/mode/example.scss

Scope — how far the plan reaches

scope decides how far the plan is allowed to look. Same source resize, different blast radius. The scene puts the source inside a Workflow group together with a sibling, plus three nodes outside the group: one connected to the source, one disconnected, and a separate Node ↔ Node island in the bottom-right.

  • GLOBAL (default) — every node and group on the canvas is eligible.
  • GROUP — restricted to the source's siblings (same fNodeParentId). Nothing outside the group is touched. Use it when each group should behave like an isolated workspace.
  • CONNECTED_SUBGRAPH — BFS from the source over connections in both directions. Only nodes reachable from the source via the graph follow it. The disconnected external node and the island stay still.

[example.html] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/scope/example.html [example.ts] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/scope/example.ts [example.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/scope/example.scss

Collision — what happens when shifts run out of room

When a shifting candidate would overlap a stationary node, collision decides who gives way. To create a stationary node deliberately, the bottom node in this scene carries the fReflowIgnore directive — it never receives a primary shift, but it stays visible to the collision resolver as an obstacle.

Drag the source down toward the anchored node and switch the rule:

  • STOP (default) — the shifting candidate is clamped at the spacing line in front of the anchor. The remainder of the delta is dropped, the anchor doesn't move.
  • CHAIN_PUSH — the anchor is absorbed into the plan and pushed too. If it then collides with the next node, that one moves as well, bounded by maxCascadeDepth. Useful for dense layouts where you'd rather everything cascade than have shifts visually disappear.

[example.html] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/collision/example.html [example.ts] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/collision/example.ts [example.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/collision/example.scss

fReflowIgnore is the directive you reach for when a node has to stay pinned regardless of what the rest of the graph does — annotations, legend labels, stats panels.

Delta source — by how much each candidate moves

deltaSource decides how the shift magnitude is computed once a candidate is picked. The source has only the top and bottom handles — drag the top handle upward to see the difference clearly: the source grows, but only its top edge moves; the bottom stays where it is.

  • EDGE_BASED (default, recommended) — each candidate follows the edge that actually moved. Top edge moved up → only the node above is pushed up. Bottom stayed put → the node below stays put.
  • CENTER_BASED — the full size delta is applied to candidates picked by centre comparison. The node below shifts down even though the source's bottom edge never moved, because the source's centre moved up. Visibly wrong for asymmetric resize.

EDGE_BASED is the right choice in almost every case. CENTER_BASED is kept for layouts where every resize is symmetric (always grows from the centre).

[example.html] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/delta-source/example.html [example.ts] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/delta-source/example.ts [example.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/delta-source/example.scss

Axis — which directions trigger reflow

axis filters which size changes the plan reacts to. The source carries all four directional handles and sits in the middle of four cardinal neighbours.

  • BOTH (default) — vertical and horizontal passes run independently. Drag any handle and the matching neighbour follows.
  • VERTICAL — only height changes count. Dragging the left or right handles pushes nothing.
  • HORIZONTAL — only width changes count. Dragging the top or bottom handles pushes nothing.

Switch to VERTICAL or HORIZONTAL when one of the axes is fully managed by your own layout (e.g. you snap nodes to a column grid) and you don't want reflow second-guessing it.

[example.html] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/axis/example.html [example.ts] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/axis/example.ts [example.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/axis/example.scss

Runtime config via FReflowController

FReflowController is provided at the same injector as provideFFlow(...), so any component below the provider can inject it directly:

setConfig(...) accepts a partial config and merges it with what's already there. The change takes effect on the next resize — no provider rebuild, no graph rebuild. Use it for runtime UI: a "freeze layout" toggle while a user does bulk edits, switching mode from CENTER_OF_MASS to DOWNSTREAM_CONNECTIONS when entering a different editing mode, etc.

Click Disable reflow, drag the source's bottom handle: the neighbours stay put. Re-enable and the next drag does shift them again.

[example.html] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/pattern-live-controller/example.html [example.ts] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/pattern-live-controller/example.ts [example.scss] <<< https://raw.githubusercontent.com/Foblex/f-flow/main/libs/f-examples/plugins/reflow-on-resize/pattern-live-controller/example.scss

Edit this page on GitHub