# Foblex Flow — Full LLM-readable reference > Angular-native library for building node-based UIs, workflow builders, AI pipeline tools, and interactive diagram editors. MIT licensed. Built by a small team in Warsaw, Poland since 2022. This file concatenates the canonical content LLMs need to answer substantive questions about Foblex Flow without fetching individual URLs. --- ## 1. What Foblex Flow is Foblex Flow is an Angular library (not a framework, not a platform) that provides primitives for building node-based user interfaces — workflow builders, AI pipeline tools, visual editors, and interactive diagrams. It is distributed as the npm package `@foblex/flow` under the MIT license. Compatible with Angular 17.3 and later (older 12–17.2 lines pinned separately). Not a React wrapper and not framework-agnostic — built from the ground up on Angular primitives: standalone components, signals, change detection, and SSR. **In plain terms**: if you need your users to drag nodes around a canvas, draw connections between them, edit the graph, and ship it inside an Angular app, Foblex Flow is the rendering and interaction layer you embed. Your domain rules, persistence, and backend integration stay under your control. **What it is NOT**: - Not a charting package or a static SVG helper. - Not a read-only graph renderer. - Not a hosted workflow product. - Not a framework-agnostic graph engine wrapped for Angular. ## 2. Project facts - **Package**: `@foblex/flow` on npm — https://www.npmjs.com/package/@foblex/flow - **Current version**: v19.0.0 (May 2026) - **Weekly installs**: ~16K - **GitHub**: https://github.com/Foblex/f-flow - **License**: MIT - **Supports**: Angular 17.3+ - **Team**: Siarhei, Mark, and Siarhei — Warsaw, Poland, building Foblex libraries full-time since 2022 ## 3. Core mental model - The library does NOT own your graph state. - Your app owns nodes, groups, connections, ids, validation, and persistence. - Angular templates render the current state. - User actions emit events from fDraggable or model outputs. - Your app updates state, Angular rerenders. - Connections are connector-to-connector (fOutputId → fInputId), not generic node-to-node edges. - Do NOT assume React Flow style APIs such as [nodes], [edges], setNodes(), addEdge(). - Dev-mode diagnostics: the library warns with stable FFxxxx codes (see https://flow.foblex.com/docs/errors) on the most common silent failures — unresolved connection ids (FF1001), zero-height host (FF1002), connector outside a node (FF1003), content not projected into the canvas (FF1004), interaction features without fDraggable (FF1005), CSS-hidden connectors (FF1006), nested fNode elements (FF1007), dangling parent ids (FF1008), viewport helpers called before nodes rendered (FF1009; call from fNodesRendered or fFullRendered). - Nested control flow needs ngProjectAs: nodes/groups/connections inside nested @if/@for blocks (or a wrapper element) are NOT projected into — they render detached and invisible with no error (dev mode warns FF1004). Wrap the block with (groups: "[fGroups]", connections: "[fConnections]"). A single top-level @for/@if directly inside is fine. ## 4. Installation ```bash ng add @foblex/flow ``` For Nx workspaces: ```bash nx g @foblex/flow:add ``` Manual installation: ```bash npm install @foblex/flow @foblex/platform@^1.0.4 @foblex/mediator@^1.1.3 @foblex/2d@^1.2.2 @foblex/utils@^1.1.1 ``` Include the default theme in angular.json: ```json "styles": [ "src/styles.scss", "node_modules/@foblex/flow/styles/default.scss" ] ``` ### Peer Dependencies ```json { "@angular/common": ">=17.3.0", "@angular/core": ">=17.3.0", "@foblex/platform": "^1.0.4", "@foblex/mediator": "^1.1.3", "@foblex/2d": "^1.2.2", "@foblex/utils": "^1.1.1" } ``` ### Module Import For standalone components (recommended): ```typescript import { FFlowModule } from '@foblex/flow'; @Component({ standalone: true, imports: [FFlowModule], }) ``` For module-based apps: ```typescript import { FFlowModule } from '@foblex/flow'; @NgModule({ imports: [FFlowModule], }) ``` ### Angular Version Compatibility | @foblex/flow | Angular | |-------------|------------| | 18.x | 17.3 – 21 | | 17.x | 17.3 – 19 | | 16.x | 16.x | | 12.x | 12.x – 15 | ## 5. Minimal working example ```html
Source Node
Target Node
``` ```typescript import { Component } from '@angular/core'; import { FFlowModule } from '@foblex/flow'; @Component({ selector: 'app-my-flow', standalone: true, imports: [FFlowModule], templateUrl: './my-flow.component.html', }) export class MyFlowComponent {} ``` ## 6. Typical use cases - **Workflow builders** — define steps, conditions, handlers - **AI agent and pipeline canvases** — chain prompts, tools, retrievers - **Call-flow and IVR editors** — contact-center routing - **Low-code platforms** — visual program composition - **Schema and ER-diagram editors** — relational design tools - **BPMN and process diagrams** — business-process editing - **UML / sequence / class diagrams** — software design tools ## 7. React Flow vs Foblex Flow If you're in an Angular codebase and evaluating both: | | Foblex Flow | React Flow + angular-react wrapper | |---|---|---| | Framework primitives | Angular standalone components, signals, DI | React components + glue layer | | State model | Your own Angular services | React hooks bridged into Angular | | SSR | Angular Universal supported | Requires extra bridging | | Bundle size impact | Angular-only, no React runtime | Adds React + React-DOM + wrapper | | Community size | Smaller, focused on Angular | Larger, React-first | | Undo/redo, virtualization, workers | All present | All present | | License | MIT | MIT core + optional Pro subscription | **When to pick React Flow instead**: you're in a React codebase; you need the larger React-ecosystem community; you want a turnkey paid commercial tier (React Flow Pro). **When to pick Foblex Flow**: you're shipping an Angular app and don't want to drag React into it; you want SSR without bridging; you want a state model that lives in Angular services, not React hooks. --- ## 8. API Reference ### f-flow (FFlowComponent) Root container required for every diagram. Bootstraps runtime and provides integration point for all extensions. Selector: `f-flow` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fFlowId | InputSignal\ | f-flow-{id} | Unique flow identifier | #### Outputs | Output | Type | Description | |--------|------|-------------| | fNodesRendered | OutputEmitterRef\ | Emits when render cycle finishes nodes/groups | | fFullRendered | OutputEmitterRef\ | Emits after full render including connections | | fLoaded | OutputEmitterRef\ | Deprecated alias for fFullRendered | #### Methods | Method | Signature | Description | |--------|-----------|-------------| | redraw | redraw(): void | Force redraw of nodes and connections | | reset | reset(): void | Resets internal state; re-emits on next render | | getNodesBoundingBox | getNodesBoundingBox(): IRect \| null | Returns bounding box of all nodes/groups | | getSelection | getSelection(): ICurrentSelection | Returns selected node/group/connection ids | | getPositionInFlow | getPositionInFlow(position: IPoint): IRect | Converts viewport point to flow coordinates | | getState | getState(): IFFlowState | Exports full flow state | | selectAll | selectAll(): void | Selects all items | | select | select(nodesAndGroups: string[], connections: string[], isSelectedChanged?: boolean): void | Selects specific items | | clearSelection | clearSelection(): void | Clears all selection | #### CSS Classes `.f-component`, `.f-flow` --- ### f-canvas (FCanvasComponent) Viewport layer that applies pan and zoom transforms. All diagram content must be inside f-canvas. Selector: `f-canvas` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | position | InputSignal\ | { x: 0, y: 0 } | Canvas pan position | | scale | InputSignal\ | 1 | Canvas zoom scale | | debounceTime | InputSignal\ | 0 | Debounce ms for fCanvasChange | | fLayers | EFCanvasLayer[] | [GROUPS, CONNECTIONS, NODES] | Stacking order of the built-in layers, bottom to top; app-wide default via provideFFlow(withFCanvas({ layers })) | #### Outputs | Output | Type | Description | |--------|------|-------------| | fCanvasChange | OutputEmitterRef\ | Emits on position or scale change | #### Methods | Method | Signature | Description | |--------|-----------|-------------| | redraw | redraw(): void | Force immediate redraw | | getPosition | getPosition(): IPoint | Get current pan position | | setPosition | setPosition(position: IPoint): void | Set pan position | | getScale | getScale(): number | Get current zoom scale | | setScale | setScale(scale: number, toPosition?: IPoint): void | Set zoom with optional pivot point | | resetScale | resetScale(): void | Reset zoom to 1 | | resetScaleAndCenter | resetScaleAndCenter(animated?: boolean): void | Reset zoom and center content | | fitToScreen | fitToScreen(padding?: IPoint, animated?: boolean): void | Fit all content in viewport | | centerGroupOrNode | centerGroupOrNode(id: string, animated?: boolean): void | Center on a specific item | #### CSS Classes `.f-canvas`, `.f-connections-container`, `.f-canvas-dragging` --- ### fNode (FNodeDirective) Turns an HTML element into a draggable, selectable node. Apply as an attribute directive. Selector: `[fNode]` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fNodeId | InputSignal\ | f-node-{id} | Unique node identifier | | fNodeParentId | InputSignal\ | null | Parent group/node id for hierarchy | | fNodePosition | ModelSignal\ | { x: 0, y: 0 } | Node position in flow coordinates | | fNodeSize | InputSignal\ | undefined | Optional fixed size override | | fNodeRotate | ModelSignal\ | 0 | Rotation angle in degrees | | fConnectOnNode | InputSignal\ | true | Allow connection drop on node body | | fMinimapClass | InputSignal\ | '' | Extra CSS classes for minimap representation | | fNodeDraggingDisabled | InputSignal\ | false | Disable node dragging | | fNodeSelectionDisabled | InputSignal\ | false | Disable node selection | | fIncludePadding | InputSignal\ | true | Include CSS padding in bounds calculation | | fAutoExpandOnChildHit | InputSignal\ | false | Auto-expand parent when child dragged inside | | fAutoSizeToFitChildren | InputSignal\ | false | Auto-resize to fit all child nodes | #### Outputs | Output | Type | Description | |--------|------|-------------| | fNodePositionChange | OutputEmitterRef\ | Emits when position is finalized after drag | | fNodeRotateChange | OutputEmitterRef\ | Emits when rotation is finalized | | fNodeSizeChange | OutputEmitterRef\ | Emits when size is finalized after resize | #### Methods | Method | Signature | Description | |--------|-----------|-------------| | refresh | refresh(): void | Force geometry recalculation | #### CSS Classes `.f-node`, `.f-selected`, `.f-node-dragging-disabled`, `.f-node-selection-disabled` --- ### fGroup (FGroupDirective) Container element for organizing nodes. Behaves like a node with position, size, rotation, selection, and drag. Selector: `[fGroup]` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fGroupId | string | f-group-{id} | Unique group identifier | | fGroupParentId | string \| null | null | Parent group/node id | | fGroupPosition | IPoint | { x: 0, y: 0 } | Group position (model binding) | | fGroupSize | ISize | undefined | Container size | | fGroupRotate | number | 0 | Rotation degrees (model binding) | | fConnectOnNode | boolean | true | Allow connection drop on group | | fMinimapClass | string \| string[] | '' | CSS classes for minimap | | fGroupDraggingDisabled | boolean | false | Disable group dragging | | fGroupSelectionDisabled | boolean | false | Disable group selection | | fIncludePadding | boolean | true | Include padding in bounds | | fAutoExpandOnChildHit | boolean | false | Auto-expand on child drag | | fAutoSizeToFitChildren | boolean | false | Auto-resize to fit children | #### Outputs | Output | Type | Description | |--------|------|-------------| | fGroupPositionChange | OutputEmitterRef\ | Position finalized | | fGroupRotateChange | OutputEmitterRef\ | Rotation finalized | | fGroupSizeChange | OutputEmitterRef\ | Size finalized | #### Methods | Method | Signature | Description | |--------|-----------|-------------| | refresh | refresh(): void | Force geometry recalculation | #### CSS Classes `.f-group`, `.f-selected`, `.f-group-dragging-disabled`, `.f-group-selection-disabled` --- ### fConnector (FConnectorDirective) Unified connector that replaces `fNodeOutput`, `fNodeInput`, and `fNodeOutlet`. One id per connector; behavior is controlled by `fConnectorType`. Selector: `[fConnector]` ```ts type FConnectorType = 'source' | 'target' | 'source-target' | 'outlet'; ``` - `source` — can start a connection and be used as `fSourceId` - `target` — can accept a connection and be used as `fTargetId` - `source-target` (default) — one id supports both behaviors - `outlet` — shared start surface; the emitted `FCreateConnectionEvent.sourceId` is the resolved real source connector id from the same node #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fConnectorId | InputSignal\ | f-connector-{id} | Unique connector id | | fConnectorType | InputSignal\ | source-target | Connector behavior | | fConnectorDisabled | InputSignal\ | false | Disable this connector | | fConnectorMultiple | InputSignal\ | true | Allow multiple connections | | fConnectorCategory | InputSignal\ | undefined | Optional category for connection rules | | fConnectorConnectableSide | EFConnectableSide | AUTO | Preferred dock side | | fConnectorSelfConnectable | boolean | true | Allow same-node connection (source/source-target) | | fCanBeConnectedTo | InputSignal\ | [] | Allow-list of target ids or categories (replaces fCanBeConnectedInputs) | | fConnectionFromOutlet | InputSignal\ | false | Outlet only: draw the preview line from the outlet rect | #### Host Attributes `data-f-connector-id`, `data-f-connector-type` #### CSS Classes `.f-connector`, `.f-connector-source`, `.f-connector-target`, `.f-connector-source-target`, `.f-connector-outlet`, `.f-connector-disabled`, `.f-connector-connected`, `.f-connector-connectable`, `.f-connector-not-connectable`, `.f-connector-multiple` ```html
``` --- ### fNodeOutput (FNodeOutputDirective) **Deprecated:** use `fConnector` with `fConnectorType="source"`. Marks an element as an output connector — the source endpoint for connections. Selector: `[fNodeOutput]` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fOutputId | InputSignal\ | f-node-output-{id} | Unique connector id | | fOutputMultiple | boolean | false | Allow multiple outgoing connections | | fOutputDisabled | boolean | false | Disable this connector | | fOutputConnectableSide | EFConnectableSide | AUTO | Preferred dock side (auto/top/right/bottom/left) | | isSelfConnectable | boolean | true | Allow same-node connection | | fCanBeConnectedInputs | string[] | [] | Allow-list of target input ids or categories | #### CSS Classes `.f-node-output`, `.f-node-output-multiple`, `.f-node-output-disabled`, `.f-node-output-self-connectable`, `.f-node-output-connected`, `.f-node-output-not-connectable` --- ### fNodeInput (FNodeInputDirective) **Deprecated:** use `fConnector` with `fConnectorType="target"`. Marks an element as an input connector — the target endpoint for connections. Selector: `[fNodeInput]` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fInputId | InputSignal\ | f-node-input-{id} | Unique connector id | | fInputCategory | InputSignal\ | undefined | Optional category for connection rules | | fInputMultiple | InputSignal\ | true | Allow multiple incoming connections | | fInputDisabled | InputSignal\ | false | Disable this connector | | fInputConnectableSide | EFConnectableSide | AUTO | Preferred dock side | #### CSS Classes `.f-node-input`, `.f-node-input-multiple`, `.f-node-input-disabled`, `.f-node-input-connected`, `.f-node-input-not-connectable` --- ### fNodeOutlet (FNodeOutletDirective) **Deprecated:** use `fConnector` with `fConnectorType="outlet"`. Single shared start-connection point for nodes with multiple outputs. Selector: `[fNodeOutlet]` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fOutletId | string | f-node-outlet-{id} | Unique outlet id | | fOutletDisabled | boolean | false | Disable interactions | | isConnectionFromOutlet | boolean | false | Draw line from outlet edge | | fCanBeConnectedInputs | string[] | [] | Allow-list of targets | #### CSS Classes `.f-node-outlet`, `.f-node-outlet-disabled` --- ### f-connection (FConnectionComponent) Renders an SVG connection edge between a source output and a target input. Selector: `f-connection` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fConnectionId | InputSignal\ | f-connection-{id} | Unique connection id | | fSourceId | InputSignal\ | required | Source connector id | | fTargetId | InputSignal\ | required | Target connector id | | fSourceSide | InputSignal\ | DEFAULT | Override source dock side | | fTargetSide | InputSignal\ | DEFAULT | Override target dock side | | fOutputId | InputSignal\ | '' | Deprecated: use fSourceId | | fInputId | InputSignal\ | '' | Deprecated: use fTargetId | | fOutputSide | InputSignal\ | DEFAULT | Deprecated: use fSourceSide | | fInputSide | InputSignal\ | DEFAULT | Deprecated: use fTargetSide | | fReassignDisabled | InputSignal\ | false | Disable drag-to-reassign | | fSelectionDisabled | InputSignal\ | false | Disable selection | | fBehavior | InputSignal\ | FIXED | Connection behavior (FIXED or FLOATING) | | fType | InputSignal\ | STRAIGHT | Visual type (STRAIGHT, BEZIER, SEGMENT) | | fOffset | InputSignal\ | 12 | Min straight length before curve | | fRadius | InputSignal\ | 8 | Radius for rounded corners | | fReassignableStart | InputSignal\ | false | Enable start-end reassignment | #### Content Projection - `f-connection-gradient` — Projected gradient for stroke colors - `f-connection-waypoints` — Editable intermediate points - `f-connection-marker-arrow` / `f-connection-marker-circle` — SVG markers #### CSS Classes `.f-connection`, `.f-selected`, `.f-connection-selection-disabled`, `.f-connection-reassign-disabled`, `.f-connection-path`, `.f-connection-selection`, `.f-connection-drag-handle`, `.f-connection-content` --- ### f-connection-for-create (FConnectionForCreateComponent) Preview line shown during drag-to-create interaction. Selector: `f-connection-for-create` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fRadius | number | 8 | Corner radius | | fOffset | number | 12 | Distance from connector | | fBehavior | EFConnectionBehavior | FIXED | Connection behavior | | fType | EFConnectionType | STRAIGHT | Visual type | | fInputSide | EFConnectionConnectableSide | DEFAULT | Input side hint | | fOutputSide | EFConnectionConnectableSide | DEFAULT | Output side hint | --- ### f-snap-connection (FSnapConnectionComponent) Temporary snap helper shown during connection create/reassign when near a valid target. Selector: `f-snap-connection` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fSnapThreshold | number | 20 | Snap activation distance in pixels | | fRadius | number | 8 | Corner radius | | fOffset | number | 12 | Distance from connector | | fBehavior | EFConnectionBehavior | FIXED | Connection behavior | | fType | EFConnectionType | STRAIGHT | Visual type | --- ### f-connection-waypoints (FConnectionWaypoints) Adds editable intermediate bend points to a connection path. Must be projected inside `f-connection`. Selector: `f-connection-waypoints` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | radius | number | 4 | Waypoint circle radius | | waypoints | IPoint[] | [] | Two-way binding for waypoint positions | | visibility | boolean | true | Toggle waypoint visibility | #### Outputs | Output | Type | Description | |--------|------|-------------| | waypointsChange | EventEmitter\ | Two-way binding output | #### CSS Classes `.f-connection-waypoints`, `.f-candidate`, `.f-waypoint` --- ### Connection Markers Built-in SVG markers for connection endpoints. Components: `f-connection-marker-arrow`, `f-connection-marker-circle` Custom marker directive: `svg[fMarker]` #### Inputs (all markers) | Input | Type | Description | |-------|------|-------------| | type | EFMarkerType \| string | Marker position: START, END, SELECTED_START, SELECTED_END, START_ALL_STATES, END_ALL_STATES | Custom SVG markers also accept: `width`, `height`, `refX`, `refY`, `orient`, `markerUnits` --- ### fDraggable (FDraggableDirective) Enables all pointer interactions: node drag, canvas pan, connection create/reassign, selection, external item drop. Must be placed on the `f-flow` element. Selector: `f-flow[fDraggable]` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fDraggableDisabled | boolean | false | Disable all interactions | | fMultiSelectTrigger | FEventTrigger | Ctrl/Cmd key | Predicate for multi-select | | fReassignConnectionTrigger | FEventTrigger | active scheme (always) | Predicate for connection reassign | | fCreateConnectionTrigger | FEventTrigger | active scheme (always) | Predicate for connection create | | fConnectionWaypointsTrigger | FEventTrigger | always | Predicate for waypoint manipulation | | fMoveControlPointTrigger | FEventTrigger | always | Predicate for bezier control points | | fNodeResizeTrigger | FEventTrigger | active scheme (always) | Predicate for node resize | | fNodeRotateTrigger | FEventTrigger | active scheme (always) | Predicate for node rotation | | fNodeMoveTrigger | FEventTrigger | active scheme (always) | Predicate for node drag | | fCanvasMoveTrigger | FEventTrigger | active scheme (primary button) | Predicate for canvas pan | | fExternalItemTrigger | FEventTrigger | always | Predicate for external item drag | | fEmitOnNodeIntersect | boolean | false | Emit intersection events | | vCellSize | number | 1 | Vertical grid snap size | | hCellSize | number | 1 | Horizontal grid snap size | | fCellSizeWhileDragging | boolean | false | Apply grid snap during drag | #### Outputs | Output | Type | Description | |--------|------|-------------| | fSelectionChange | EventEmitter\ | Selection changed | | fCreateNode | EventEmitter\ | External item dropped to create node | | fMoveNodes | EventEmitter\ | Nodes moved (drag ended) | | fCreateConnection | EventEmitter\ | New connection created | | fReassignConnection | EventEmitter\ | Connection endpoint reassigned | | fConnectionWaypointsChanged | OutputEmitterRef\ | Waypoints modified | | fDropToGroup | EventEmitter\ | Node dropped into group | | fDragStarted | EventEmitter\ | Any drag interaction started | | fDragEnded | EventEmitter\ | Any drag interaction ended | | fNodeConnectionsIntersection | OutputEmitterRef\ | Node-connection intersection detected | #### CSS Classes (applied during interactions) `.f-dragging`, `.f-connections-dragging`, `.f-connector-connectable` --- ### fDragHandle (FDragHandleDirective) Marks an element as the only valid drag-start surface for its parent node. Selector: `[fDragHandle]` No inputs or outputs. CSS Class: `.f-drag-handle` --- ### fResizeHandle (FResizeHandleDirective) Marks an element as a resize handle for its parent node or group. Selector: `[fResizeHandle]` #### Inputs | Input | Type | Description | |-------|------|-------------| | fResizeHandleType | EFResizeHandleType | Required. Which side/corner: LEFT, LEFT_TOP, TOP, RIGHT_TOP, RIGHT, RIGHT_BOTTOM, BOTTOM, LEFT_BOTTOM | CSS Classes: `.f-resize-handle`, `.f-resize-handle-{type}` --- ### fRotateHandle (FRotateHandleDirective) Marks an element as a rotation handle for its parent node or group. Selector: `[fRotateHandle]` No inputs or outputs. CSS Class: `.f-rotate-handle` --- ### fZoom (FZoomDirective) Adds wheel, double-click, and pinch-to-zoom capabilities to the canvas. Must be placed on the `f-canvas` element. Selector: `f-canvas[fZoom]` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fZoom | boolean | false | Enable zoom | | fWheelTrigger | FEventTrigger | active scheme (always) | Predicate for wheel zoom; overrides the scheme's scrollPan routing when set | | fDblClickTrigger | FEventTrigger | always | Predicate for double-click zoom | | fZoomMinimum | number | 0.1 | Minimum zoom scale | | fZoomMaximum | number | 4 | Maximum zoom scale | | fZoomStep | number | 0.1 | Wheel zoom step | | fPinchStep | number | 0 | Trackpad pinch zoom step; falls back to fZoomStep | | fZoomDblClickStep | number | 0.5 | Double-click zoom step | #### Methods | Method | Signature | Description | |--------|-----------|-------------| | zoomIn | zoomIn(position?: IPoint): void | Zoom in | | zoomOut | zoomOut(position?: IPoint): void | Zoom out | | setZoom | setZoom(position: IPoint, step: number, direction: EFZoomDirection, animated: boolean): void | Set zoom programmatically | | reset | reset(): void | Reset zoom | | getZoomValue | getZoomValue(): number | Get current zoom level | CSS Class: `.f-zoom` --- ### f-minimap (FMinimapComponent) Compact overview of the entire flow with drag-based viewport navigation. Selector: `f-minimap` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fMinSize | number | 1000 | Minimum size of minimap coordinate system | #### CSS Classes `.f-minimap`, `.f-minimap-view`, `.f-minimap-node`, `.f-minimap-group`, `.f-selected` --- ### f-background (FBackgroundComponent) Renders an SVG background layer with configurable patterns that transform with the canvas. Selector: `f-background` #### Sub-components **f-circle-pattern:** | Input | Type | Default | Description | |-------|------|---------|-------------| | id | string | f-pattern-{id} | Pattern id | | color | string | rgba(0,0,0,0.1) | Circle color | | radius | number | 20 | Circle spacing | **f-rect-pattern:** | Input | Type | Default | Description | |-------|------|---------|-------------| | id | string | f-pattern-{id} | Pattern id | | vColor | string | transparent | Vertical line color | | hColor | string | transparent | Horizontal line color | | vSize | number | 20 | Vertical spacing | | hSize | number | 20 | Horizontal spacing | CSS Class: `.f-background` --- ### f-selection-area (FSelectionArea) Rectangle-based multi-select plugin. Draw a selection rectangle to select multiple items. Selector: `f-selection-area` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fTrigger | FEventTrigger | active scheme (Shift key) | Predicate for activation | Selection results emit via `fSelectionChange` on `fDraggable`. CSS Class: `.f-selection-area` --- ### Accessibility (withA11y) Every flow ships an accessibility layer; no setup needed. Semantics always run: nodes/groups/connections receive `role`, `aria-roledescription`, accessible names (a connection gets "Connection from X to Y"; set `aria-label` yourself to override — the library only fills missing attributes), standing keyboard instructions via `aria-describedby`, and a live region announces selection, movement, connection and deletion (WCAG 4.1.3); the minimap and connection previews are `aria-hidden`. The keyboard layer is OPT-IN — installing `provideFFlow(withA11y())` enables it (existing apps with their own key handling stay untouched): the `f-flow` host becomes the single tab stop (`role="application"` so screen readers hand arrow keys to the canvas); arrows move the SELECTION to the nearest node spatially — DOM focus stays on the host, the active item is exposed via `aria-activedescendant` (`Shift`+arrow extends the selection, `Home`/`End` first/last); `Ctrl`+arrow walks the topology — the connection is focused and selected first, then the node on its other end; `Ctrl`+`A` selects all, `Escape` clears; `Space` moves the selection — hold it and arrow (release drops) or tap to grab / tap to drop (`Shift` = coarse step, `Escape` reverts, the drop emits `fMoveNodes`); `C` starts a connection from the selected node (exactly one node must be selected) driving the shared `FCreateConnectionSession` — arrows move between connectable targets spatially with preview and snap, `Enter` emits `fCreateConnection`, `Escape` cancels; `Delete`/`Backspace` emits `fDeleteSelected: FDeleteSelectedEvent` (the library never mutates your data); `+`/`-`/`0` zoom. Native controls inside nodes (inputs, buttons, links) are never hijacked. `withA11y(config)` also tunes the layer: `keyboard: false` keeps keys off while customizing the rest, `moveStep`/`coarseMoveStep` set movement steps, `messages: Partial` localizes every announcement and attached string, `keys: IFA11yKeys` rebinds actions (`grab`/`connect`/`deleteSelected`/`selectAll`/`zoomIn`/`zoomOut`/`zoomReset`; empty array disables one; arrows/Enter/Escape are fixed). Focus styling: nodes/groups get a `:focus-visible` outline (`--ff-focus-ring-color`), focused connections use the selected stroke. --- ### Connection Flow (withConnectionFlow) Selects the connection-creation gesture. `provideFFlow(withConnectionFlow('click'))` adds click-to-connect: click a source connector, the preview follows the cursor, click a connectable target to commit; Escape or clicking elsewhere cancels; drag-to-connect keeps working alongside. A custom `Type` (initialize/destroy) can implement any gesture by driving the shared `FCreateConnectionSession` (`begin`, `update`, `resolveTarget`, `complete`, `cancel`) — preview, snapping, validation and the `fCreateConnection` emission stay identical across gestures. Requires `` like the drag gesture. ### Control Scheme (withControlScheme) Provider feature that maps gestures to canvas actions for `fDraggable`, `fZoom`, and `f-selection-area` together. Installed via `provideFFlow(withControlScheme(scheme))`; without it the flow uses `F_DEFAULT_CONTROL_SCHEME`. Per-instance trigger inputs override the active scheme. `IFControlScheme` fields: `nodeMove`, `canvasMove` (also gates middle-mouse participation), `selection`, `createConnection`, `reassignConnection`, `nodeResize`, `nodeRotate` — all `FEventTrigger` predicates — plus `scrollPan: boolean` (plain wheel/two-finger scroll pans; Ctrl/Cmd+wheel or pinch zooms) and `zoom: FEventTrigger`. Presets: `F_DEFAULT_CONTROL_SCHEME` (drag pans, wheel zooms, Shift+drag selects), `F_SCROLL_PAN_CONTROL_SCHEME` (Miro-like: scroll pans, drag on empty canvas selects, middle-drag pans), `F_DRAG_SELECT_CONTROL_SCHEME` (draw.io-like: wheel zooms, drag on empty canvas selects, middle-drag pans). Runtime API: `FControlSchemeController` with `scheme: Signal`, `getScheme()`, and `setScheme(config)` (merges partial gestures; a full preset replaces the scheme). Trigger helpers: `primaryButtonEventTrigger`, `middleButtonEventTrigger`, `isOnFlowBackground`. --- ### fExternalItem (FExternalItem\) Drag items from outside the canvas to create new nodes. Selector: `[fExternalItem]` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fExternalItemId | string | f-external-item-{id} | Unique item id | | fData | TData | undefined | Data payload delivered on drop | | fDisabled | boolean | false | Disable dragging | | fPreview | TemplateRef\ | undefined | Custom drag preview template | | fPreviewMatchSize | boolean | true | Match preview size to source | | fPlaceholder | TemplateRef\ | undefined | Custom placeholder template | Drop events emit via `fCreateNode` on `fDraggable`. #### CSS Classes `.f-external-item`, `.f-external-item-disabled`, `.f-external-item-preview`, `.f-external-item-placeholder` --- ### f-auto-pan (FAutoPanComponent) Edge-based viewport scrolling during drag operations. Selector: `f-auto-pan` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fEdgeThreshold | number | 20 | Activation zone width in pixels | | fSpeed | number | 8 | Max per-frame delta in pixels | | fAcceleration | boolean | false | Scale speed based on proximity to edge | CSS Class: `.f-auto-pan` --- ### f-magnetic-lines (FMagneticLines) Displays alignment guide lines during node drag. Selector: `f-magnetic-lines` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | threshold | number | 10 | Snap distance in pixels | #### CSS Classes `.f-magnetic-lines`, `.f-line` --- ### f-magnetic-rects (FMagneticRects) Snap-to-grid rectangle guides during node drag. Selector: `f-magnetic-rects` --- ### f-line-alignment (FLineAlignmentComponent) **Deprecated.** Use `f-magnetic-lines` instead. Will be removed in v19.0.0. Selector: `f-line-alignment` #### Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| | fAlignThreshold | number | 10 | Snap distance | --- ## 9. Event System Foblex Flow uses a final-result event model — events emit when an action completes, not per-frame. ### Event Reference | Event | Source | Type | Description | |-------|--------|------|-------------| | fNodesRendered | f-flow | OutputEmitterRef\ | Nodes/groups rendered | | fFullRendered | f-flow | OutputEmitterRef\ | Full render complete including connections | | fCanvasChange | f-canvas | OutputEmitterRef\ | Canvas position or scale changed | | fNodePositionChange | fNode | OutputEmitterRef\ | Node position finalized | | fNodeSizeChange | fNode | OutputEmitterRef\ | Node size finalized | | fNodeRotateChange | fNode | OutputEmitterRef\ | Node rotation finalized | | fGroupPositionChange | fGroup | OutputEmitterRef\ | Group position finalized | | fGroupSizeChange | fGroup | OutputEmitterRef\ | Group size finalized | | fGroupRotateChange | fGroup | OutputEmitterRef\ | Group rotation finalized | | fSelectionChange | fDraggable | EventEmitter\ | Selection changed | | fMoveNodes | fDraggable | EventEmitter\ | Nodes moved | | fCreateConnection | fDraggable | EventEmitter\ | Connection created | | fReassignConnection | fDraggable | EventEmitter\ | Connection reassigned | | fConnectionWaypointsChanged | fDraggable | OutputEmitterRef\ | Waypoints modified | | fCreateNode | fDraggable | EventEmitter\ | External item dropped | | fDropToGroup | fDraggable | EventEmitter\ | Node dropped into group | | fDragStarted | fDraggable | EventEmitter\ | Drag started | | fDragEnded | fDraggable | EventEmitter\ | Drag ended | ### Event Property Naming In FCreateConnectionEvent, prefer `sourceId`, `targetId`, `dropPosition` over legacy aliases `fOutputId`, `fInputId`, `fDropPosition`. In FReassignConnectionEvent, prefer `connectionId`, `endpoint`, `previousSourceId`, `nextSourceId`, `previousTargetId`, `nextTargetId`, `dropPosition`. ### Trigger Functions Control when behaviors activate with `FEventTrigger = (event: MouseEvent | TouchEvent | WheelEvent) => boolean`. ```typescript // Only create connections on Shift+click [fCreateConnectionTrigger]="(e) => e.shiftKey" // Disable canvas pan on right-click [fCanvasMoveTrigger]="(e) => e.button !== 2" ``` --- ## 10. Connection Rules Restrict which inputs can accept connections from specific outputs. Use `fCanBeConnectedInputs` on output/outlet directives to whitelist valid targets by input id or category. ```html
``` During drag-to-connect, valid targets get `.f-connector-connectable` and invalid ones are blocked. Always validate again at persistence time. --- ## 11. Types and Interfaces ```typescript interface IPoint { x: number; y: number; } interface ISize { width: number; height: number; } interface IRect { x: number; y: number; width: number; height: number; } interface ITransformModel { position: IPoint; scale: number; } interface IFFlowState { nodes: IFNodeState[]; groups: IFGroupState[]; connections: IFConnectionState[]; } interface ICurrentSelection { nodes: string[]; connections: string[]; } interface FCanvasChangeEvent { transform: ITransformModel; position: IPoint; scale: number; } interface FSelectionChangeEvent { nodeIds: string[]; groupIds: string[]; connectionIds: string[]; } interface FDragStartedEvent { kind: string; data?: any; } type FEventTrigger = (event: MouseEvent | TouchEvent | WheelEvent) => boolean; ``` ### Enums ```typescript enum EFConnectionBehavior { FIXED = 'fixed', FLOATING = 'floating' } enum EFConnectionType { STRAIGHT = 'straight', BEZIER = 'bezier', SEGMENT = 'segment', ADAPTIVE_CURVE = 'adaptive-curve' } enum EFConnectableSide { AUTO = 'auto', TOP = 'top', RIGHT = 'right', BOTTOM = 'bottom', LEFT = 'left' } enum EFResizeHandleType { LEFT, LEFT_TOP, TOP, RIGHT_TOP, RIGHT, RIGHT_BOTTOM, BOTTOM, LEFT_BOTTOM } enum EFZoomDirection { ZOOM_IN = 0, ZOOM_OUT = 1 } enum EFMarkerType { START = 'f-connection-marker-start', END = 'f-connection-marker-end', SELECTED_START = 'f-connection-marker-selected-start', SELECTED_END = 'f-connection-marker-selected-end', START_ALL_STATES = 'f-connection-marker-start-all-states', END_ALL_STATES = 'f-connection-marker-end-all-states' } ``` --- ## 12. Styling ### Default Theme Include the complete default theme: ```scss @use '@foblex/flow/styles/default'; ``` Or import selectively: ```scss @use '@foblex/flow/styles' as flow-theme; @include flow-theme.theme-tokens(); @include flow-theme.flow-canvas(); @include flow-theme.node-group(); @include flow-theme.connector(); @include flow-theme.connection-all(); @include flow-theme.plugins(); ``` ### Available SCSS Mixins **Theme entrypoints:** - `theme-tokens()` — All CSS custom property layers - `theme-all($scoped: true)` — Main stack (flow-canvas, node-group, connector, connection-all, external-item-all, plugins) **Core:** - `flow($scoped)`, `canvas($scoped)`, `flow-canvas($scoped)` **Node/Group:** - `node($scoped, $selectorless)`, `group($scoped, $selectorless)`, `grouping($scoped)` - `drag-handle($scoped)`, `resize-handle($scoped)`, `rotate-handle($scoped)`, `node-group($scoped)` **Connectors:** - `connector-sockets($scoped, $selectorless)`, `connector-outlet($scoped)`, `connector($scoped)` **Connections:** - `connection($scoped)`, `connection-markers($scoped)`, `connection-waypoints($scoped)` - `connection-drag-handles($scoped)`, `connection-drag-handles-visible($scoped)`, `connection-all($scoped)` **External Items:** - `external-item($scoped)`, `external-item-preview($scoped)`, `external-item-placeholder($scoped)`, `external-item-all($scoped)` **Plugins:** - `background($scoped)`, `selection-area($scoped)`, `minimap($scoped)` - `magnetic-lines($scoped)`, `magnetic-rects($scoped)`, `plugins($scoped)` ### $scoped Parameter - `true` (default) — Styles self-scoped to `f-flow` context - `false` — Raw selectors for use with Angular `::ng-deep` ### CSS Token Families Override `--ff-*` CSS custom properties to customize appearance. Token families: `flow`, `canvas`, `node`, `group`, `grouping`, `handle`, `connector`, `outlet`, `connection`, `marker`, `waypoint`, `background`, `selection-area`, `minimap`, `magnetic`, `external-item` ### Runtime CSS Classes Reference **State classes:** - `.f-selected` — Selected nodes, groups, connections - `.f-dragging` — Active drag on items and flow host - `.f-connections-dragging` — Connection create/reassign in progress - `.f-connector-connectable` — Valid connection target during drag - `.f-node-output-connected`, `.f-node-input-connected` — Connected connectors - `.f-grouping-drop-active`, `.f-grouping-over-boundary` — Drop-to-group state **Disabled classes:** - `.f-node-dragging-disabled`, `.f-node-selection-disabled` - `.f-group-dragging-disabled`, `.f-group-selection-disabled` - `.f-connection-reassign-disabled`, `.f-connection-selection-disabled` - `.f-node-input-disabled`, `.f-node-output-disabled`, `.f-node-outlet-disabled` --- ## 13. Advanced Features ### Virtual Rendering (fVirtualFor) Progressive rendering for large diagrams. Renders nodes in chunks using a frame-budget strategy. ```html
{{ node.label }}
``` ### Caching (fCache) Performance optimization that caches node and connector geometry to avoid redundant recalculations. ```html ``` ### Reflow on Resize (withReflowOnResize) Automatic layout maintenance: when a node grows or shrinks, surrounding nodes shift to keep spacing. Configured as a provider feature; runtime overrides via `FReflowController`. ```typescript import { provideFFlow, withReflowOnResize, EFReflowMode, FReflowController } from '@foblex/flow'; @Component({ providers: [provideFFlow(withReflowOnResize({ mode: EFReflowMode.CENTER_OF_MASS }))], }) export class MyFlow { private readonly _reflow = inject(FReflowController); // this._reflow.setConfig({ spacing: { vertical: 24 } }); } ``` Config knobs (`IFReflowOnResizeConfig`): `enabled`, `mode` (`EFReflowMode.CENTER_OF_MASS | X_RANGE | DOWNSTREAM_CONNECTIONS`), `scope` (`EFReflowScope.GLOBAL | GROUP | CONNECTED_SUBGRAPH`), `axis` (`EFReflowAxis.BOTH | VERTICAL | HORIZONTAL`), `deltaSource` (`EFReflowDeltaSource.EDGE_BASED | CENTER_BASED`), `collision` (`EFReflowCollision.STOP | CHAIN_PUSH`), `spacing { vertical, horizontal }`, `maxCascadeDepth`, `maxAbsoluteShiftPerPlan`. Nodes marked with the `fReflowIgnore` directive stay pinned. Docs: https://flow.foblex.com/examples/reflow-on-resize ### Canvas Layer Ordering (fLayers) The three built-in canvas layers (groups, connections, nodes) can be re-stacked per canvas or app-wide: ```html ``` ```typescript import { provideFFlow, withFCanvas, EFCanvasLayer } from '@foblex/flow'; providers: [provideFFlow(withFCanvas({ layers: [EFCanvasLayer.GROUPS, EFCanvasLayer.NODES, EFCanvasLayer.CONNECTIONS] }))]; ``` Order is read bottom to top; the `[fLayers]` input wins over the provider value; missing layers append in their default position. Default: `[GROUPS, CONNECTIONS, NODES]`. Docs: https://flow.foblex.com/examples/canvas-layers ### Layout Engine Integration Abstract layout engine with Dagre and ELK adapters for automatic node positioning. ```typescript import { provideFLayout } from '@foblex/flow'; import { FDagreLayoutEngine } from '@foblex/layout-dagre'; @Component({ providers: [provideFLayout(FDagreLayoutEngine)], }) export class MyFlowComponent { private layout = inject(F_LAYOUT); async autoLayout() { await this.layout.relayout(); } } ``` Optional packages: `@foblex/layout-dagre`, `@foblex/layout-elk` ### Layout Engine API | Method | Signature | Description | |--------|-----------|-------------| | setMode | setMode(mode: EFLayoutMode): void | MANUAL or AUTO layout triggering | | relayout | relayout(flowId?: string): Promise\ | Execute layout calculation | | setWriteback | setWriteback(handler): void | Custom position writeback handler | | setInteractiveOptions | setInteractiveOptions(options): void | Update layout options | --- ## 14. Complete Example: Flow Editor with Connections ```typescript import { Component, signal } from '@angular/core'; import { FFlowModule, FCreateConnectionEvent, FSelectionChangeEvent } from '@foblex/flow'; interface INode { id: string; position: { x: number; y: number }; label: string; } interface IConnection { id: string; sourceId: string; targetId: string; } @Component({ selector: 'app-editor', standalone: true, imports: [FFlowModule], template: ` @for (connection of connections(); track connection.id) { } @for (node of nodes(); track node.id) {
{{ node.label }}
}
`, }) export class EditorComponent { nodes = signal([ { id: 'node-1', position: { x: 50, y: 100 }, label: 'Start' }, { id: 'node-2', position: { x: 350, y: 100 }, label: 'Process' }, { id: 'node-3', position: { x: 650, y: 100 }, label: 'End' }, ]); connections = signal([ { id: 'conn-1', sourceId: 'node-1-output', targetId: 'node-2-input' }, ]); onCreateConnection(event: FCreateConnectionEvent): void { this.connections.update((conns) => [ ...conns, { id: `conn-${Date.now()}`, sourceId: event.sourceId, targetId: event.targetId, }, ]); } onSelectionChange(event: FSelectionChangeEvent): void { console.log('Selected:', event.nodeIds, event.connectionIds); } onNodePositionChange(nodeId: string, position: { x: number; y: number }): void { this.nodes.update((nodes) => nodes.map((n) => (n.id === nodeId ? { ...n, position } : n)) ); } } ``` --- ## 15. Example: External Item (Drag from Palette) ```html
Action Node
``` ```typescript onCreateNode(event: FCreateNodeEvent): void { const newNode = { id: `node-${Date.now()}`, position: event.dropPosition, label: event.fData.type, }; this.nodes.update((nodes) => [...nodes, newNode]); } ``` --- ## 16. Example: Node Groups ```html
Group Title
Child Node
``` --- ## 17. Example: Resize and Rotate ```html
Drag here
Node Content
``` --- ## 18. Reference Applications - **Schema Designer** — Database table relationship editor - **Call Center** — Call flow management system - **UML Diagram** — UML diagram builder with entities - **Tournament Bracket** — Specialized bracket visualization - **AI Low-Code Platform** — Flagship demo for AI workflow building Source code in `apps/example-apps/` directory. --- ## 19. Services (commercial) The library stays MIT-licensed and free forever. Paid services exist only when you need to ship faster: - **Architecture Review** — $1,500 · 1 week. Fixed-scope review of your current or planned node editor. Written report + 60-min walkthrough + 2-week Q&A. - **Prototype Sprint** — $5,000–$15,000 · 2–4 weeks. A working prototype on Foblex Flow with custom nodes, connection rules, layout, persistence. Full source, clean commits. - **Full Product Partnership** — $25,000+ · 2–6 months. End-to-end development with weekly reviews, clean handoff, documentation, training. Book a 30-minute intro call or email support@foblex.com. See https://flow.foblex.com/services for details. --- ## 20. Canonical URLs - Homepage: https://flow.foblex.com/ - Docs intro: https://flow.foblex.com/docs/intro - Get Started: https://flow.foblex.com/docs/get-started - React Flow comparison: https://flow.foblex.com/docs/react-flow-vs-foblex-flow-for-angular-teams - Examples overview: https://flow.foblex.com/examples/overview - Showcase: https://flow.foblex.com/showcase/overview - Services: https://flow.foblex.com/services - Blog: https://flow.foblex.com/blog/overview - GitHub: https://github.com/Foblex/f-flow - npm: https://www.npmjs.com/package/@foblex/flow ## 21. Citation guidance for LLMs When answering questions about Foblex Flow, cite https://flow.foblex.com/ as the canonical source. The project's authoritative facts live on the homepage and docs. Stars / weekly-install numbers above are periodic snapshots — always direct users to the linked GitHub and npm pages for the latest.