synergycodes/ng-diagram/ng-diagram-custom-nodes
Claude Code and agent skill by synergycodes/ng-diagram
- community
Checking that the SKILL.md file is still in the repository.
Use when building ng-diagram node templates (NgDiagramNodeTemplateMap), customizing the default node, autoSize vs size, inputs or Angular Material inside nodes (data-no-drag), disabling dragging, or "Node template ... is not registered".
Install
npx vskill@latest install synergycodes/ng-diagram/ng-diagram-custom-nodesSKILL.md
Custom node templates
How to write, register and size node templates, put interactive content in them, and control dragging and selection styling. Ports are in ng-diagram-ports, resize/rotate handles in ng-diagram-resize-rotate-snap, group templates in ng-diagram-groups, hiding in ng-diagram-visibility.
Rules
- Template contract. A node template is a standalone component that implements
NgDiagramNodeTemplate<TData>and declaresnode = input.required<Node<TData>>(). The diagram renders it withngComponentOutletand passes the node through an input namednode, so the name must be exactlynode. - Registration. Add the component to a
NgDiagramNodeTemplateMap, bind the map with[nodeTemplateMap], and use the same key as the node'stype. A node withouttypeuses the default node. An unknowntypelogs[ngDiagram] Node template '<type>' is not registered. Falling back to default node template.once and renders the default node (the default group template forisGroupnodes). - Size.
autoSizedefaults totrue: the content decides the size, and the library writes the measured size intonode.size. Asizeyou set is not applied in this mode. For a fixed size setsizeandautoSize: false. A user resize setsautoSize: falsefor you. - Fill the node box. With a fixed size the library sizes the node wrapper, not your component. Give your component host
display: block(orflex),width: 100%andheight: 100%, so the content and the selection shadow match the node size. - Do not mutate `node()`. Change nodes through
NgDiagramModelService.updateNodeDatareplaces the wholedataobject, so spread the old data. Never write the system-ownedmeasuredPorts,measuredBounds,computedZIndexorcomputedHidden. - Interactive elements (inputs, selects, scroll areas) need
data-no-drag="true"anddata-no-pan="true". Otherwise pressing them drags the node or pans the canvas.
Minimal custom node + registration
Without ports a node cannot start or receive a drawn edge (see ng-diagram-ports).
Default node and NgDiagramBaseNodeTemplateComponent
A node without type uses the default node. It shows data.label (the node id when data has no label key), is at least 11.25rem × 2rem in auto-size mode, shows resize and rotate handles when selected, and has two ports, port-left and port-right, both type="both".
<ng-diagram-base-node-template [node]="node()">wraps your content in the default look, the resize/rotate handles, the selection style and the default ports.[removeDefaultPorts](since 1.3.0):trueremoves the default ports,falsekeeps them even whendefaultNode.removePortsistrue. When it is not set, the config decides.- The config option is read through the
config()signal, which is filled atdiagramInit: the default ports render (and are measured) during initialization and disappear right after it. For no default ports from the first render, use[removeDefaultPorts]="true"in your own template. - The
[config]binding is read when the model is initialized. To changedefaultNode(or any option) later, callNgDiagramService.updateConfig({ defaultNode: { removePorts: true } }). - Restyle the default node with CSS variables on a container:
--ngd-node-bg-primary-default(background),--ngd-node-border-color,--ngd-node-border-color-hover,--ngd-node-border-radius,--ngd-node-border-size,--ngd-txt-primary-default(text),--ngd-selected-node-box-shadow. Themes and tokens:ng-diagram-styling.
Inputs, buttons and scrollable content
- The library checks the pointer target with
closest('[data-no-drag="true"]'), so the attribute works on the element or on any wrapper. The value must be the string"true":data-no-drag="true"and[attr.data-no-drag]="true"work, a baredata-no-dragdoes not. data-no-dragstops only the node drag. The press still selects the node, and because the node no longer takes the drag, moving the pointer pans the canvas. That is why inputs needdata-no-pantoo.data-no-panalso stops wheel panning, so scroll areas inside a node scroll. Ctrl/⌘ + wheel still zooms the diagram.- No attribute stops selection. Stop the
pointerdownpropagation on the element, as the docs examples do for their toggle buttons. - Diagram shortcuts skip key events only from
input,textarea,selectandcontenteditableelements. In other focused widgets (mat-select, custom dropdowns, buttons) the arrow keys also move the selected node and Delete/Backspace delete the selection; stop those keys' propagation in the widget. Shortcut setup:ng-diagram-shortcuts.
Read references/interactive-content.md for two complete, type-checked templates: a note node (input, scrollable list, button, data updates) and an Angular Material select node (based on the docs example angular-material-node).
Dragging on and off
- Both stop pointer drags and arrow-key moves. The node can still be selected, resized and connected. Programmatic moves (
moveNodesBy,updateNode) ignore both flags. nodeDraggingEnabled: falsewins: a node withdraggable: truestill cannot be dragged. (Some docs text says the node property has priority; the source requires both.)- When the selection cannot move, the arrow keys pan the viewport (since 1.4.0).
- With dragging off, pressing a node and moving the pointer pans the canvas. To stop that for such nodes, put
data-no-pan="true"on the template host (this also stops wheel panning over the node);viewportPanningEnabled: falsestops all panning.
Selection styling
NgDiagramNodeSelectedDirective(as a host directive, orngDiagramNodeSelected [node]="node()"on an inner element) adds the classesng-diagram-node-wrapperandng-diagram-node-selected. The global styles then drawbox-shadow: var(--ngd-selected-node-box-shadow). The element needsdisplay: blockorflex, or the shadow is invisible.- For your own style, read
node().selected:
Hiding part of a node vs hiding the node
- Content inside your template: use
@ifor your own CSS. WithautoSizethe node is measured again. - Ports: use the port's
[hidden]input, not CSS (seeng-diagram-ports). - The whole node: the model
hiddenflag or[ngDiagramHidden](since 1.4.0). Neverdisplay: noneon your component host: an auto-size node then never gets a valid size, its ports are never measured, initialization waits for the measurement timeouts (2 to 4 s), and the library still treats the node as visible (selection,zoomToFit). Seeng-diagram-visibility.
Edge cases
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/ng-diagram-custom-nodes/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/synergycodes/ng-diagram/ng-diagram-custom-nodes)