Diagram - Inspector composition

Use generic selection controls, replace sections and keep semantic notation forms within their own roots.

#Usage

import { Diagram } from '@primeui/vue-diagram';
<Diagram.Root :store="store" page-id="page">
    <Diagram.Viewport label="Workflow editor" style="height: 24rem" />
    <Diagram.Inspector v-slot="{ selectedIds, commands, execute }">
        <p>{{ selectedIds.length }} selected</p>
        <button v-for="command in commands" :key="command.id" type="button" :disabled="!command.available" :title="command.reason" @click="execute(command.id)">{{ command.label }}</button>
    </Diagram.Inspector>
</Diagram.Root>

The definition receives selected records, command states, and public authoring actions from the runtime inspector.

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

#UI Composition

Use copied inspector sections to edit the current selection. They share the root's useDiagramSelectionInspector() model, so controls follow current selection and policy. This fragment assumes the store from First Diagram.

import { Diagram } from '@primeui/vue-diagram';
import { DiagramInspectorUI } from '@ui/diagram';
<Diagram.Root :store="store" page-id="page">
    <DiagramInspectorUI />
    <Diagram.Viewport label="Workflow" style="height: 24rem" />
</Diagram.Root>

Each section reuses the root’s DiagramSelectionInspectorModel. Compose these sections for replacement UI; content inside DiagramInspectorUI appends to its generic controls.

The generic inspector edits a selected shape or connector using the root's DiagramSelectionInspectorModel. It follows the current selection and policy; selecting a locked item does not make its saved fields editable.

#Handle empty, single and mixed selections

Choose a selection, then compare Lock request and Read only. You can also select on canvas: the selector reflects that live choice, including other selections. The inspector reports the outcome of supported edits in its own status region.

Loading Demo...

Choose a selection, toggle Lock request or Read only, and compare the controls. Selection does not grant edit permission. Empty selection shows a hint; one shape exposes Name/Label, Transform and Arrange; one connector exposes connector properties, Label and Arrange. Multiple/mixed selection shows its count and available group actions. Operation feedback appears in the status region.

Name edits data.title; Label edits saved scene text. Do not repeat a centered title beneath an authored label. Transform uses current geometry and saved bounds/rotation as appropriate. The copied connector form exposes its supported subset, rather than every record property.

SelectionGeneric controls
EmptySelection hint
One shapeName/label, Transform and Arrange
One connectorConnector properties, label and Arrange
Multiple or mixed recordsSelection count and available group Arrange actions

Name changes data.title; the label control edits or creates the supported saved label. The canvas renders saved labels separately from custom node content. Avoid painting a duplicate centered title behind an authored centered label. Transform reads current geometry for position and saved bounds/rotation where applicable. Connector conversion and decorator choices follow the copied part's actual subset; it is not a generic form for every record property.

Projected content in DiagramInspectorUI appends after those controls and status. It cannot replace its generic body through a named slot.

#Compose only the sections you need

The custom sidebar specimen uses DiagramLabelUI and DiagramTransformUI directly. DiagramArrangeUI and DiagramConnectorPropertiesUI are independent sections too. Each injects the same root-provided selection model. Preserve an empty-selection hint and expose status from useDiagramSelectionInspector() in your own reserved status region; sections alone do not render all the generic inspector's feedback.

Import DiagramLabelUI, DiagramTransformUI, DiagramArrangeUI and DiagramConnectorPropertiesUI from your copied UI entry and put the chosen sections in a root-descendant panel. DiagramInspectorUI appends its default slot after its generic controls; that slot does not replace them.

For a custom panel, make a child component under the root and read its shared model. Destructure refs for template unwrapping:

<script setup lang="ts">
import { useDiagramSelectionInspector } from '@primeui/vue-diagram';
import { DiagramLabelUI, DiagramTransformUI } from '@ui/diagram';

const { status, selectedCount } = useDiagramSelectionInspector();
</script>

<template>
    <aside class="diagram-inspector-body" aria-label="Selection properties">
        <p v-if="!selectedCount">Select a shape or connector.</p>
        <DiagramLabelUI />
        <DiagramTransformUI />
        <p role="status">{{ status }}</p>
    </aside>
</template>

Snapshots are readonly. Custom actions use flat methods such as setName(id, value), setCoordinate(id, axis, value), setSize(id, axis, value) and setRotation(id, value). Use the returned canonical value/outcome; do not assign to the model's refs. For a different authoring surface, Diagram.Inspector offers a scoped slot with selection, commands, availability(action) and apply(action).

#Edit one of several saved labels

DiagramLabelListUI and DiagramLabelPropertiesUI share the root's selection model. Clicking canvas text selects its owner and exact label. The list chooses a saved label by ID; properties edit that label rather than always editing the first one. Use these parts instead of DiagramLabelUI when an application needs multiple-label controls. The existing generic inspector keeps its simpler name/first-label form.

Loading Demo...

Click canvas text or choose a saved label by ID. DiagramLabelListUI and DiagramLabelPropertiesUI edit that label instead of always choosing the first. Text and numbers save on leaving a field; choices save when selected. Fields include alignment, rotation, stacking, font and connector path offsets. Centered inside layout owns placement and disables X/Y. Clear optional font fields to inherit the theme. Specifying a saved font family does not load its font resource.

Current policy, history and host approval govern changes. A pending/rejected edit keeps fields canonical. A selection change does not move a draft into another record. Keep shared status visible in a custom composition.

Both shapes and connectors expose text, alignment, rotation, stacking and font family, size, weight and color. X/Y edit the saved owner-local coordinates; centered-inside layout disables these fields because layout owns placement. Connector path fraction and normal/tangent offsets remain separate from X/Y. Clear an optional font field to inherit the theme, or use Use theme color. The component interface keeps Geist; a saved label family uses resources that your application registers and does not load or embed fonts automatically. Text and number fields save when you leave the field; choices save when selected. Create or remove labels through the public content editor when your application needs those actions. No selected record or no saved labels produces an empty state.

The root's content editor owns validation, permissions, history and controlled approval. Fields remain canonical while an edit awaits approval or is rejected. Changing selection does not carry an edit into another record. Display the shared model's readonly status ref alongside a custom composition so users can understand outcomes.

#Keep notation fields in their semantic context

Optional copied notation inspectors come from local @ui/diagram/bpmn, /uml, /er, /activity and /sequence entries. Put each under its corresponding semantic root, which itself belongs under a Diagram root. Bind inherited entityId to a supported saved node/connector ID; null is not a universal form for the current selection. The BPMN form can also expose page-level catalogs.

The UI-parts reference lists providers/imports. The BPMN, UML class, ER, Activity and Sequence guides show their typed authoring workflows. Schema Modeler combines the ER form with an application sidebar.

Notation forms require their matching semantic root under Diagram.Root, and their store must have the matching notation module. Runtime roots/hosts come from @primeui/vue-diagram/bpmn, /uml, /er, /activity or /sequence; copied forms come from the corresponding local UI subpath. Bind entityId to a supported saved record. Null is not a universal selection form; BPMN can also offer page catalogs. Generic inspector data cannot infer notation semantics.

#Compose a notation inspector

Notation sections use one explicitly scoped model. Import the matching runtime host and only the copied sections your application needs. For example, an ER entity editor can omit relationship controls:

Place this composition under a Diagram root whose Store has the ER module. selectedId identifies the saved entity. All three parts share the host's model, including drafts and read-only/pending feedback. The complete ER inspector uses the same sections. BPMN, UML, Activity and Sequence follow this pattern; the UI part catalog lists the coherent groups for each family.

For an ER-only entity panel, import DiagramErRoot and DiagramErInspectorHost from /er, then place copied DiagramErEntityUI, DiagramErFieldsUI and DiagramErStatusUI inside the host under that root. All share one scoped model. Set root showDefaultStatus false only if your own composition presents status and warnings. This does not suppress validation or permissions.