Diagram - Node UI and native fields

Register typed node templates or components while keeping geometry, native editing and saved state in the runtime.

#Usage

import { Diagram } from '@primeui/vue-diagram';
<Diagram.Root :store="store" page-id="page">
    <Diagram.NodeDef node-type="task">
        <Diagram.Field name="title" v-slot="{ getInputProps }">
            <input v-bind="getInputProps({ 'aria-label': 'Task title' })" />
        </Diagram.Field>
    </Diagram.NodeDef>
    <Diagram.Viewport label="Workflow editor" style="height: 24rem" />
</Diagram.Root>

This skeleton assumes an initialized store with page page. Use First Diagram for model creation, style imports and store disposal.

#UI Composition

Register a scoped slot with Diagram.NodeDef, or render your own Vue component inside it. Both retain Diagram's shape, geometry, clipping, selection and saved data. This fragment assumes the store from First Diagram.

import { Diagram } from '@primeui/vue-diagram';
import { DiagramNodeContentUI } from '@ui/diagram';
<Diagram.Root :store="store" page-id="page">
    <Diagram.NodeDef node-type="task" v-slot="{ node }">
        <DiagramNodeContentUI align="start">
            <template #header><strong>{{ node.data?.['title'] }}</strong></template>
            <Diagram.Field name="title" v-slot="{ getInputProps }">
                <input v-bind="getInputProps({ 'aria-label': 'Saved task title' })" />
            </Diagram.Field>
            <template #footer>Waiting for review</template>
        </DiagramNodeContentUI>
    </Diagram.NodeDef>
    <Diagram.Viewport label="Tasks" style="height: 24rem" />
</Diagram.Root>

The copied content shell controls presentation. Node definitions and fields retain their runtime context and saved-data ownership.

#Switch a template and a registered component

Edit Saved title, then Enter to apply or Escape to cancel. Switch Renderer and Undo: the saved value belongs to the model, while registration belongs to the root and the mounted view.

Loading Demo...

Edit Saved title, press Enter or Escape, switch Renderer, then Undo. The title belongs to the model; renderer choice and an unrelated local draft belong to the mounted view. A child component inside the definition can call useDiagramNodeContext() to get readonly node and geometry refs plus actions. Use .value in setup and destructure top-level refs for template unwrapping.

An exact nodeType wins over fallback; the last matching declaration in source order wins. Body and ports resolve independently. There is no separate Vue component registry: render the component as definition content. Unmounting the definition removes it from that root. Avoid a broad fallback that replaces the built-in content of pools or notation nodes you want to retain.

Registration replaces the default content, including generated pool/lane headers. It does not replace the runtime shape or create a special header slot. Lay out your content within the intended bounds. Do not use an unrestricted fallback card template for notation/pool types whose own content you need.

#Project a content shell

Saved labels render in their own runtime layer. The general editor specimens omit their center title when authored labels exist. A rich card can use a separate metadata header, but it must reserve space so an authored label does not overprint its form. HTML content does not become portable SVG artwork in exports.

DiagramNodeContentUI has header, default body and footer slots. Its align defaults to center and supports start. It creates no context and writes no model data. Saved labels render separately, so reserve space for them rather than repeating the same centered title beneath a form.

#Preserve native form editing

Template/component actions exposes setData, content, rotate, edit and availability. Results still obey permissions and managed/controlled store ownership. Inspect the current result rather than writing a parallel draft engine. See Content, Geometry and measurement and the UI-parts reference.

Bind getInputProps(...) from Diagram.Field to a native input or textarea. Do not also use v-model or a competing value binding. Focus starts a draft, input updates it, blur finishes it, Enter commits an input and Escape cancels. Textarea Enter inserts a newline. IME keeps native composition behavior.

The single readOnly prop combines with current content policy, including permissions and another owned edit. Pass application props/handlers into the getter so required attributes and events stay composed. Application handlers run first; preventing the event skips Diagram's handler. A wrapper component must forward the props and ref to the native field.

Actions include setData, content, rotate, edit and availability. Read their results and diagnostics; controlled edits still need host acceptance. Readonly snapshots cannot be assigned to. Save persistent changes through these actions rather than keeping a parallel mutable node record.

#Boundary port controls

Put body content in Diagram.NodeDef and boundary buttons in Diagram.NodePortsDef. The latter sits beside the clipped body and follows its transform. Its ports contain configured local positions before measurement. Use Diagram.Port and bind getPortProps(...) to each button for measurement and connection interaction. Keep one marker per saved endpoint.

Portable output needs an explicit HTML representation; mounted in-tree rendered capture has a separate contract. Offscreen Vue content is rejected with diagnostics. See Export.