Diagram - Page links

Follow a node link to a page or task, then let the host navigate and reveal its destination.

#Usage

import { nextTick, shallowRef } from 'vue';
import { Diagram, type DiagramPageReference, type DiagramRootHandle } from '@primeui/vue-diagram';

const pageId = shallowRef('page');
const root = shallowRef<DiagramRootHandle | null>(null);
let navigation = 0;

async function followPage(target: DiagramPageReference) {
    const request = ++navigation;
    const source = store;
    const model = source.getSnapshot();
    if (!model.pages.some((page) => page.id === target.pageId)) return;
    if (target.nodeId && !model.nodes.some((node) => node.id === target.nodeId && node.pageId === target.pageId)) return;
    pageId.value = target.pageId;
    await nextTick();
    if (request !== navigation || store !== source || pageId.value !== target.pageId) return;
    const latest = source.getSnapshot();
    if (!latest.pages.some((page) => page.id === target.pageId)) return;
    if (target.nodeId && !latest.nodes.some((node) => node.id === target.nodeId && node.pageId === target.pageId)) return;
    const current = root.value;
    if (!current || current.getStore() !== source) return;
    const session = current.getSession();
    if (target.nodeId) {
        session.reveal(target.nodeId);
        session.focus(target.nodeId);
    } else {
        session.fit();
    }
}
<Diagram.Root ref="root" :store="store" :page-id="pageId" @navigate-page="followPage">
    <Diagram.Viewport label="Workflow editor" style="height: 24rem" />
</Diagram.Root>

Store page references on saved records. The application’s followPage handler selects a valid destination page and optionally reveals its target; the root does not change host navigation automatically.

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

Bind :page-id="pageId" and @navigate-page="followPage" on Diagram.Root. In followPage, validate the destination before updating the host ref. Await Vue's nextTick() before reading the new page session for reveal, and recheck that the request still belongs to the current store/page.

A node can reference another page, optionally identifying a target node on that page. This is a navigation relationship. A connector remains on its own page and cannot span independent page coordinates.

#Follow a page or a specific task

Choose Detail page and Follow to fit the destination page. Choose Review task on Details to reveal and focus that offscreen task. Selection remains a separate choice. Unavailable link source resolves no saved reference and leaves the page unchanged.

Loading Demo...
import type { DiagramPageReference } from '@primeui/vue-diagram';

const detailLink: DiagramPageReference = {
    pageId: 'details',
    nodeId: 'detail-task'
};

Store this value on a node's link. nodeId is optional for page-only navigation. Model validation requires the target page and, when supplied, a target node belonging to that page. Surviving incoming links prevent removal that would leave a dangling reference. Keep IDs stable and apply link changes atomically with related ownership edits.

#Let the application choose navigation and reveal

session.navigationTarget(sourceId) returns the saved { pageId, nodeId? } reference or null. DiagramRootHandle.followLink(sourceId) emits navigatePage when that reference exists; it does not change the host's page ref itself. Use the handle for event-time actions, and context refs in descendant components for live UI.

Handle @navigate-page="followPage" by validating the current destination, updating root pageId, then revealing after the new session and viewport have rendered. This example checks that the store/page are still current before applying its deferred reveal. For a node target it calls session.reveal(id) and focus(id); for a page it calls fit(). The host could choose another zoom, selection or focus policy. Do not pass screen coordinates or an outgoing page's session into the destination.

Reveal recenters without changing the current zoom. Focus and selection are different: focus supports keyboard navigation; select([id]) changes the selection. Hidden targets cannot become visible merely by focus. A collapsed descendant can reveal its visible ancestor; a missing or fully hidden target may produce no viewport movement. Decide whether your application should show that reason or request expansion/visibility, rather than promising every link moves the view.

#Handle unavailable references

A missing source or a source without link emits no navigatePage event. The example reports this explicitly. A well-formed saved model cannot contain a missing target page/node; malformed Store updates reject validation. A navigation request may still become stale between event delivery and host handling, so check the current destination before navigation and deferred reveal.

Changing root pageId tears down outgoing drafts and previews. Page choice is host state outside model history; Undo of a saved graph edit does not navigate back automatically. Reset restores the example's model and overview view.

See Pages and layers, Search and the Controlled State.