Diagram - Pages and layers
Place Pages and Layers independently, keep navigation in the host and edit workspace structure through shared commands.
#Usage
import { shallowRef } from 'vue';
import { Diagram } from '@primeui/vue-diagram';
import { DiagramPagesUI, DiagramLayersUI } from '@ui/diagram';
const pageId = shallowRef('page');
const layerId = shallowRef('layer');
function choosePage(id: string) {
const snapshot = store.getSnapshot();
const layer = snapshot.layers.find((item) => item.pageId === id);
if (!snapshot.pages.some((item) => item.id === id) || !layer) return;
layerId.value = layer.id;
pageId.value = id;
}<Diagram.Root :store="store" :page-id="pageId">
<Diagram.WorkspaceHost :active-layer-id="layerId" @page-change="choosePage" @layer-change="layerId = $event">
<DiagramPagesUI />
<DiagramLayersUI />
</Diagram.WorkspaceHost>
<Diagram.Viewport label="Workspace" style="height: 24rem" />
</Diagram.Root>Diagram.WorkspaceHost supplies one workspace model to both panels. The copied
DiagramWorkspaceUI is the combined composition with its own host; do not nest
another provider unnecessarily. Its activeLayerId, pageChange and layerChange
contract is the same. These are props/emits, not named v-model contracts.
This skeleton assumes an initialized store with page page. Use First Diagram for model creation, style imports and store disposal.
Pages have independent coordinate spaces. Layers order records and control their visibility or locking within one page. The application owns the active page and insertion layer; the model stores page/layer records and saved edits.
#UI Composition
import { Diagram } from '@primeui/vue-diagram';
import { DiagramPagesUI, DiagramLayersUI } from '@/components/primeui/diagram';Place the split controls under one Diagram.WorkspaceHost beneath the existing root. Bind its current activeLayerId; adopt pageChange and layerChange requests in the application. Keep page and insertion-layer IDs valid after history or model changes. The complete examples below show host ownership and cleanup.
#Place page navigation and layer management independently
Choose a page or insertion layer from the compact navigation row. Open Manage pages or Manage layers for a focused dialog to add, rename, reorder, hide, lock or remove. Opening or closing a manager leaves the canvas in place. Insert a card to see the chosen layer used by a real drawing command. Hidden or locked ownership can reject insertion.
Choose another page and insertion layer, then open Manage. Rename a page/layer, change visibility or lock state, and reorder layers. The management dialog keeps focus within its interaction; closing it returns focus to its Manage control. PrimeOne uses PrimeVue controls and Tailwind uses its themed HTML controls.
The panels need workspace context even without an editor shell. A custom child
under the host can call useDiagramWorkspace() to read readonly refs such as
pages, layers, currentPage, currentLayer and hasPending. Use its actions
for changes; never mutate the snapshots or assign to a readonly ref.
Changes apply through workspace authority as each action is confirmed. Escape or Done closes the manager and returns focus to Manage; closing does not undo a saved action. Use the editor's Undo for a committed edit. Unsubmitted names stay drafts while the same page/layer and model remain current. PrimeOne uses PrimeVue Dialog; Tailwind uses its themed HTML controls and native modal dialog. Custom controls share the host's workspace model rather than recreating its transactions or availability checks.
#Keep navigation separate from saved edits
Changing root pageId disposes the outgoing session's owned transient work and
subscriptions before binding the new session. Root and viewport DOM observers
follow their own component lifetimes; another editor's proposals remain its own. Removing an active page does not
make the Core store choose a replacement. The host must supply a surviving page.
An obsolete pageId gives an unavailable scene; an empty model is supported.
Multiple roots may maintain independent page choices over their owned stores.
Vue preserves mounted application child-local state across page changes. The root's session changes and internal owners rebind; no keyed viewport remount is required. This is separate from Reset, which deliberately recreates the example. Auto-fit is one-shot for the new session once its viewport has a nonzero size. Ordinary later size changes preserve navigation; offer Fit again when the user wants to reframe after a resize. Initial framing respects prior explicit navigation. Undo restores saved page/layer edits while the host still chooses which page to display.
An insertion layer is also host state. Bind it to the actual insertion operation,
as the example's drawing.execute(spec, bounds) does. Selecting a layer alone
does not change existing records or make every insertion tool use that layer.
See Drawing and
Palette for their insertion bindings.
pageChange requests a host page change. Keep the chosen layer valid for that
page, including after imports or removal. The complete example reconciles its
refs from store commits. activeLayerId chooses the insertion destination; it
does not move existing records to that layer. Pass it separately to a palette
target or drawing configuration that needs it.
Changing page replaces the root's page session, cancelling outgoing drafts and previews. Page selection is local host state outside model history. Structural edits, layer visibility and locks are saved model changes and follow current permissions, Undo and controlled-store acknowledgement.
#Edit page and layer records safely
| Structure command | Saved effect / policy |
|---|---|
page-add | Adds a page and its required initial layer together. |
page-update | Renames the page. |
page-remove | Requires explicit cascade when it contains layers or content; incoming navigation references reject removal. |
layer-add | Adds a layer owned by a valid page. |
layer-update | Changes only name, visible or locked. Omitted flags mean visible/unlocked. |
layer-order | Lists every layer on that page exactly once; model order controls paint order. |
layer-remove | A nonempty layer needs a different same-page relocateTo destination; contents retain their geometry and ownership hierarchy. |
The copied panels apply an additional UI policy: keep at least one page and layer, remove pages only after their nodes/connectors are cleared, and choose relocation for a populated layer. Their availability follows current editor policy. Removal controls appear in the management dialog; they do not silently cascade nonempty pages. Core permits more explicit host workflows through structural commands.
Unlocking a layer is allowed under its own saved lock while still respecting root read-only and explicit constraints. Unlock before other changes to a locked layer. Hidden layer records remain saved and searchable, but their entities are unavailable for ordinary visible selection/reveal in the copied explorer.
Use Page links for navigation references, Groups and containers for parent ownership and the Controlled State guide for host-owned proposals.