/

Creating Nodes

A node is a standalone Angular component rendered inside the editor wrapper. Extend DrawFlowBaseNode to receive graph data and to expose any input and output connectors in the component view.

Graph inputsId, model, role, selection and validation arrive as signals.
Local UIForms, menus and expanded state stay inside the Angular component.
Wrapper stylingCore owns selection and validation chrome through CSS variables.

Base Node API

SignalValueUse
nodeIdSignal()stringBuild graph-wide unique connector ids.
modelSignal()Record<string, any> & {type: string} Render application data from node.data .
startNodeSignal() / endNodeSignal()booleanApply application role rules in the template.
selectedSignal()booleanReact to editor selection inside node content.
invalidSignal()booleanCombine graph validation with local node validity.
inputs() / outputs()Connector arraysObserve connectors currently rendered by conditional templates.

Read-only compatibility getters such as nodeId and model are also available. Prefer signals in templates and computed() values.

typed-task-node.component.ts

    
      interface TaskNodeData {
  readonly type: 'task';
  readonly title: string;
  readonly status: 'draft' | 'ready';
}

export class TaskNodeComponent extends DrawFlowBaseNode {
  readonly task = computed(() => this.modelSignal() as TaskNodeData);
  readonly connectorPrefix = computed(() => `${this.nodeIdSignal()}-task`);
}
    

Role Metadata

Core does not automatically forbid incoming connections for startNode or outgoing connections for endNode . These values are metadata passed to the custom component. Render or hide the corresponding connectors to enforce that policy in the UI. The editor also uses the first start node as a preferred camera-framing anchor.

The physical connector position comes from your component CSS. The connector position input only describes the direction used to calculate the path.

Register the Node Type

Register every component under the same key used by node.data.type . Providers can be application-wide or scoped to one editor.

graph-editor.component.ts

    
      providers: [
  provideNgDrawFlowConfigs({
    nodes: {
      yourNode: YourNodeComponent,
    },
  }),
];
    

Complete Custom Node

The preview combines a component, template and styles. Wrapper background, border, padding, selection and invalid states remain configurable on ng-draw-flow instead of being duplicated in every node type.

    
      
    
    
      import {ChangeDetectionStrategy, Component} from '@angular/core';
import {DfInputComponent, DfOutputComponent, DrawFlowBaseNode} from '@ng-draw-flow/core';

@Component({
    standalone: true,
    selector: 'app-your-node',
    imports: [DfInputComponent, DfOutputComponent],
    templateUrl: './node.template.html',
    styleUrl: './node.styles.less',
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class YourNodeComponent extends DrawFlowBaseNode {}

    
    
      :host {
    display: block;
    inline-size: 10rem;
}

.input,
.output {
    position: absolute;
    z-index: 1;
}

.input {
    inset-inline-start: -0.5rem;
    inset-block-start: 0.25rem;
}

.output-wrapper {
    position: relative;
}

.output {
    inset-inline-end: -0.5rem;
    inset-block-start: 0;
}

    
    
      @if (!startNodeSignal()) {
    <df-input
        class="input"
        [connectorData]="{nodeId: nodeIdSignal(), connectorId: nodeIdSignal() + '-input-1', single: false}"
    />
}

<p class="tui-text_body-xs">{{ modelSignal().text }}</p>

@if (!endNodeSignal()) {
    <df-output
        class="output"
        [connectorData]="{nodeId: nodeIdSignal(), connectorId: nodeIdSignal() + '-output-1', single: false}"
    />
}

    

Dynamic Content

Signal queries automatically detect connectors added or removed by Angular control flow. Emit connectorsUpdated after a local UI change moves an existing connector without changing the query, so core can remeasure its anchor. Use markForCheck() only after imperative state changes Angular cannot observe.

Continue with the connector guide for multiple handles, Polymorpheus content and action outputs.