Getting StartedInstallation and setup guides 6
FormInput and selection components 26
LayoutWorkflow and structural layout components 10
NavigationMenu surfaces and hierarchical actions 7
OverlayModal and floating layer surfaces 3
FeedbackStatus, empty, progress, and loading placeholder patterns 6
UtilityGeneral-purpose interface utilities 7

Flow Editor

Flow Editor is a controlled Angular canvas for AI agents and automation workflows. Your application owns graph state and persistence; the editor renders that state and emits typed user intents.

Install

Install the optional flow package together with its TailNG and Foblex peer dependencies.

Install Flow Editor

bash
pnpm add @tailng-ui/flow @tailng-ui/components @tailng-ui/icons \
  @foblex/flow @foblex/2d @foblex/mediator @foblex/platform @foblex/utils

Global styles

Import the flow theme once in the consuming application's global stylesheet.

styles.css

css
@import '@tailng-ui/flow/styles.css';

Controlled agent workflow

Drag a palette item onto the canvas, activate it to place at center, move nodes, or use the viewport controls.

Controlled workflow with Plain CSS

Prompt builderAssemble the system and user instructions. completed
Prompt
Reasoning modelGenerate a grounded response.
1 validation warning
running

Generating the final response

Prompt Answer
ResponseReturn the final answer to the agent runtime. waiting

Waiting for model output

Answer
1 graph validation issue(s)

State ownership

Inputs are immutable graph snapshots. Handle outputs, produce new arrays or objects, and then persist those values in your application or agent backend.

agent-flow.component.ts

ts
import { Component, signal } from '@angular/core';
import {
  TngFlowEditorComponent,
  type TngFlowConnection,
  type TngFlowConnectionCreateRequest,
  type TngFlowNode,
  type TngFlowNodesMovedEvent,
  type TngFlowViewport,
} from '@tailng-ui/flow';

@Component({
  imports: [TngFlowEditorComponent],
  template: `
    <tng-flow-editor
      [nodes]="nodes()"
      [connections]="connections()"
      [presentation]="presentation"
      [validation]="validation"
      [showMinimap]="true"
      [viewport]="viewport()"
      (nodesMoved)="moveNodes($event)"
      (connectionCreateRequested)="createConnection($event)"
      (viewportChange)="viewport.set($event)"
    />
  `,
})
export class AgentFlowComponent {
  readonly nodes = signal<readonly TngFlowNode[]>(initialNodes);
  readonly connections = signal<readonly TngFlowConnection[]>(initialConnections);
  readonly viewport = signal<TngFlowViewport | null>(null);
  readonly presentation = { nodes: { model: { status: 'running' as const, progress: 68 } } };
  readonly validation = { issues: [] };

  moveNodes(event: TngFlowNodesMovedEvent): void {
    const positions = new Map(event.nodes.map((node) => [node.id, node.position]));
    this.nodes.update((nodes) =>
      nodes.map((node) => ({ ...node, position: positions.get(node.id) ?? node.position })),
    );
  }

  createConnection(event: TngFlowConnectionCreateRequest): void {
    this.connections.update((connections) => [
      ...connections,
      {
        id: crypto.randomUUID(),
        source: event.source,
        target: event.target,
        type: 'bezier',
      },
    ]);
  }
}
  • Node, port, and connection ids must be stable.
  • Port ids are unique within their node and connection endpoints include both ids.
  • presentation keeps execution state separate from persisted graph structure, while validation remains a controlled application input.

Accessibility baseline

  • The editor installs Foblex keyboard accessibility with withA11y() for spatial, topology, selection, grab/move/drop, cancellation, and controlled deletion behavior.
  • Press C on one selected node to choose an eligible source and validator-compatible target port with arrows, then confirm with Enter or Space. Port and connection status is announced throughout the operation.
  • Locked and disabled graph items are filtered, focus survives controlled updates, and focus indicators remain visible across the supported zoom range.
  • Native form controls and focusable custom-template controls keep their native keyboard behavior; graph shortcuts do not intercept their events.
  • Every connector receives a node-, direction-, and port-aware accessible label.
  • Viewport controls have text alternatives and visible keyboard focus.
  • Reduced-motion preferences suppress nonessential animation.