; fNode and fConnector are attribute directives, never
or custom elements
- Treat libs/f-flow/AI.md as the canonical generation guide; never invent selectors or bindings from prose titles
- Classic mode is the default: your app owns graph records and updates them from Foblex interaction events
- Managed mode is opt-in: provideFFlow(withFlowState()) provides typed FFlowState records, supported gesture writeback, snapshots, and undo/redo
- In both state modes your app owns domain fields, validation policy, permissions, persistence, and business meaning
- Connections are connector-to-connector: fSourceId and fTargetId reference fConnectorId values; use fConnector for new code
- Do NOT assume React Flow style APIs such as [nodes], [edges], setNodes(), addEdge()
- In classic mode handle events from fDraggable (fCreateConnection, fReassignConnection, fMoveNodes, etc.) to update app state
- Prefer non-deprecated event property names: sourceId/targetId over fOutputId/fInputId in FCreateConnectionEvent
- Import from @foblex/flow, not internal paths
### Manual Installation
Source: https://github.com/foblex/f-flow/blob/main/libs/f-flow/README.md
Install the required companion packages explicitly if you prefer to bypass the automatic CLI setup.
```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
```
--------------------------------
### Minimal ELK Layout Engine Setup
Source: https://github.com/foblex/f-flow/blob/main/libs/f-layout/elk/README.md
Demonstrates the minimal setup for using the `ElkLayoutEngine` within an Angular component. It injects the engine and uses it to calculate node positions for a simple graph structure.
```typescript
import { Component, inject } from '@angular/core';
import {
EFLayoutDirection,
IFLayoutConnection,
IFLayoutNode,
provideFLayout,
} from '@foblex/flow';
import {
EElkLayoutAlgorithm,
ElkLayoutEngine,
} from '@foblex/flow-elk-layout';
@Component({
standalone: true,
providers: [provideFLayout(ElkLayoutEngine)],
template: '',
})
export class WorkflowLayoutExample {
private readonly _layout = inject(ElkLayoutEngine);
protected async relayout(): Promise {
const nodes: IFLayoutNode[] = [
{ id: 'A' },
{ id: 'B' },
{ id: 'C' },
];
const connections: IFLayoutConnection[] = [
{ source: 'A', target: 'B' },
{ source: 'A', target: 'C' },
];
const result = await this._layout.calculate(nodes, connections, {
direction: EFLayoutDirection.TOP_BOTTOM,
algorithm: EElkLayoutAlgorithm.LAYERED,
nodeGap: 32,
layerGap: 48,
layoutOptions: {
'elk.layered.spacing.nodeNodeBetweenLayers': '64',
},
});
const positions = new Map(result.nodes.map((node) => [node.id, node.position]));
console.log(positions.get('A'));
}
}
```
--------------------------------
### Install F-Flow via CLI
Source: https://github.com/foblex/f-flow/blob/main/README.md
Use these commands to install the library in standard Angular or Nx workspaces.
```bash
ng add @foblex/flow
```
```bash
nx g @foblex/flow:add
```
--------------------------------
### Install Dagre Layout Adapter for Nx Workspaces
Source: https://github.com/foblex/f-flow/blob/main/libs/f-layout/dagre/README.md
For Nx workspaces, use the `nx g` command to generate and add the Dagre layout adapter.
```bash
nx g @foblex/flow-dagre-layout:add
```
--------------------------------
### Minimal Dagre Layout Engine Setup in Angular
Source: https://github.com/foblex/f-flow/blob/main/libs/f-layout/dagre/README.md
Demonstrates the minimal setup for using the DagreLayoutEngine within an Angular component. It injects the engine and provides it via `provideFLayout`, then calculates node positions for a simple graph.
```typescript
import { Component, inject } from '@angular/core';
import {
EFLayoutDirection,
IFLayoutConnection,
IFLayoutNode,
provideFLayout,
} from '@foblex/flow';
import {
DagreLayoutEngine,
EDagreLayoutAlgorithm,
} from '@foblex/flow-dagre-layout';
@Component({
standalone: true,
providers: [provideFLayout(DagreLayoutEngine)],
template: '',
})
export class WorkflowLayoutExample {
private readonly _layout = inject(DagreLayoutEngine);
protected async relayout(): Promise {
const nodes: IFLayoutNode[] = [
{ id: 'A' },
{ id: 'B' },
{ id: 'C' },
];
const connections: IFLayoutConnection[] = [
{ source: 'A', target: 'B' },
{ source: 'B', target: 'C' },
];
const result = await this._layout.calculate(nodes, connections, {
direction: EFLayoutDirection.LEFT_RIGHT,
algorithm: EDagreLayoutAlgorithm.NETWORK_SIMPLEX,
nodeGap: 32,
layerGap: 48,
});
const positions = new Map(result.nodes.map((node) => [node.id, node.position]));
console.log(positions.get('A'));
}
}
```
--------------------------------
### Install F-Flow Manually
Source: https://github.com/foblex/f-flow/blob/main/README.md
Install the core library and required companion packages explicitly if not using the automated CLI command.
```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
```
--------------------------------
### Install Dagre Layout Adapter Skipping Theme
Source: https://github.com/foblex/f-flow/blob/main/libs/f-layout/dagre/README.md
If your application manages its own Flow styles, use the `--skipTheme` flag during `ng add` to prevent the default theme wiring.
```bash
ng add @foblex/flow-dagre-layout --skipTheme
```
--------------------------------
### Implement a Minimal Node Editor
Source: https://github.com/foblex/f-flow/blob/main/libs/f-flow/README.md
A basic setup using f-flow, f-canvas, f-node, and f-connector directives to create a draggable node interface with a connection.
```html
```
--------------------------------
### Implement a minimal Foblex Flow editor
Source: https://github.com/foblex/f-flow/blob/main/README.md
Uses f-flow and f-canvas components to create a basic node editor with draggable nodes and a connection between them.
```html
```
--------------------------------
### Apply Selective SCSS Mixins
Source: https://github.com/foblex/f-flow/blob/main/libs/f-flow/README.md
Use these mixins to selectively include F-Flow styles instead of the full default theme entrypoint.
```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();
```
--------------------------------
### Apply Selective SCSS Mixins
Source: https://github.com/foblex/f-flow/blob/main/README.md
Use specific SCSS mixins for granular control over theme components instead of the full default stylesheet.
```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();
```
--------------------------------
### Initialize Managed State
Source: https://github.com/foblex/f-flow/blob/main/libs/f-flow/AI.md
Configure the flow state feature within a component provider and initialize the state with empty records.
```typescript
interface EditorNode extends IFStateNode {
text: string;
}
@Component({
providers: [provideFFlow(withFlowState())],
})
export class Editor {
protected readonly state = injectFlowState();
constructor() {
this.state.load({ nodes: [], groups: [], connections: [] });
}
}
```
--------------------------------
### Configure Default Theme in angular.json
Source: https://github.com/foblex/f-flow/blob/main/README.md
Add the default theme stylesheet to the styles array in your angular.json file.
```json
"styles": [
"src/styles.scss",
"node_modules/@foblex/flow/styles/default.scss"
]
```
--------------------------------
### Configure Flow Component
Source: https://github.com/foblex/f-flow/blob/main/libs/f-flow/AI.md
Import FFlowModule into the component's standalone imports to enable node, connector, and connection directives.
```typescript
// component — FFlowModule is required: fNode, fConnector, f-connection are not standalone
import { FFlowModule } from '@foblex/flow';
@Component({
standalone: true,
imports: [FFlowModule],
templateUrl: './flow.html',
styleUrl: './flow.scss',
})
export class Flow {}
```
--------------------------------
### Define Flow Template
Source: https://github.com/foblex/f-flow/blob/main/libs/f-flow/AI.md
Structure the flow using the mandatory f-flow > f-canvas hierarchy with nodes and connections.
```html
```
--------------------------------
### Handle Async Reflow in Transactions
Source: https://github.com/foblex/f-flow/blob/main/libs/f-flow/AI.md
Wrap asynchronous layout changes in a batch transaction to ensure multiple state updates are treated as a single undoable action.
```typescript
state.beginBatch();
try {
state.updateNode(nodeId, { isExpanded });
await new Promise((resolve) => {
requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
});
} finally {
state.endBatch();
}
```
--------------------------------
### Apply Flow Styles
Source: https://github.com/foblex/f-flow/blob/main/libs/f-flow/AI.md
Ensure the f-flow element has a defined height, otherwise the canvas will not be visible.
```scss
/* styles — f-flow must have a nonzero height or nothing is visible */
f-flow {
display: block;
height: 600px;
}
```
--------------------------------
### Dynamic Layer Rendering with @for and @switch
Source: https://github.com/foblex/f-flow/blob/main/libs/f-flow/src/f-canvas/f-canvas.component.html
This snippet demonstrates how to iterate over resolved layers and conditionally render content based on the layer type using Angular's @for and @switch directives.
```html
@for (layer of resolvedLayers(); track layer) { @switch (layer) { @case ('groups') {
} @case ('connections') {
} @case ('nodes') {
} } }
```
--------------------------------
### Using ngProjectAs for Nested Control Flow
Source: https://github.com/foblex/f-flow/blob/main/libs/f-flow/AI.md
Wrap nodes and connections in ng-container with ngProjectAs when using nested @if or @for blocks to ensure correct projection into the f-canvas.
```html
@if (isEditable()) {
@for (node of nodes(); track node.id) {
{{ node.label }}
}
@for (c of connections(); track c.id) {
}
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.