Diagram - Swimlanes

Create pools with lanes and phases, edit their layout, and transfer content through swimlane commands.

#Usage

import { Diagram } from '@primeui/vue-diagram';
<Diagram.Root :store="store" page-id="page">
    <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.

A pool organizes ordinary diagram content into lanes, optionally partitioned by phases. It uses the same model, store and history as other nodes. Generic pool authoring does not introduce BPMN participant/process semantics; use the BPMN module when those semantics matter.

#Start with a pool and its lanes

The example opens with two lanes and a connector between their tasks. Apply Horizontal or Vertical to the same saved pool, then Fit. Compare top and left participant headers without rebuilding the model.

Loading Demo...

A node's pool contains ordered lanes and phases. Lane IDs reference actual container nodes whose parentId and laneOf point to the pool. A direct lane child uses that lane as parentId; optional phaseId assigns it to a phase. Nested descendants inherit placement and do not repeat direct phase membership. Pool and lane dimensions must match layoutDiagramPool(pool); individual lane records cannot be independently moved, rotated, duplicated or reparented.

import { layoutDiagramPool, type DiagramPool } from '@primeui/vue-diagram';

const pool: DiagramPool = {
    orientation: 'horizontal',
    length: 360,
    lanes: [
        { id: 'intake', name: 'Intake', size: 160, minSize: 120 },
        { id: 'fulfillment', name: 'Fulfillment', size: 160, minSize: 120 }
    ],
    phases: []
};
const geometry = layoutDiagramPool(pool);

The public Vue entry exports pool types, layout and the existing session swimlane editor. The viewport includes its authoring tools; no new lane provider is needed. A complete pool can be created atomically with session.swimlanes.execute({ kind: 'create', node }), which creates the layout-owned lane records. The saved fixtures here explicitly contain those records and layout bounds before the initial store is created.

Pool settingDefault / meaning
orientationRequired. Horizontal stacks lanes vertically and phases horizontally; Vertical swaps these axes.
headerPositionOmitted/top puts the participant strip above; left puts it at the left edge.
headerSize32 participant-header units; zero hides the strip.
laneHeaderSize80 lane-header units; zero hides the strip.
phaseHeaderSize28 with phases; no phase strip when phases: []. Zero hides it.
lengthExplicit along-axis content extent for a lane-only pool; phase sizes determine that extent when phases exist.
Lane/phase size and minSizeFinite sizes of at least 32, further restricted by a supplied minimum. A pool needs at least one lane; lane contents may be empty.

Default rendering uses pool/lane data and layout-local header geometry. A type-specific Diagram.NodeDef slot or its child component replaces the default node content, including its headers. It is not an automatically positioned header slot: the host must lay out the replacement within the pool/lane bounds. Keep ordinary task templates separate from pool/lane types. Pool movement/rotation and compatible nesting use the ordinary editor. Orientation changes transpose content placement while retaining each task's orientation.

#Size, reorder and collapse lanes; edit phases

Choose a lane and Apply size in the copied properties part. Add a named lane, then Undo to remove it. Reverse the lanes or collapse the selected lane. Phase operations grow a partition, reorder phases, insert Handoff, or compare occupied removal with explicit membership clearing. Reset before an occupied-removal attempt so the phase still owns its task. Clearing Plan membership can fit the remaining body. Clearing Deliver membership retains its former position beyond that body, so the command rejects; clearing membership does not waive geometry checks.

Loading Demo...

DiagramSwimlanePropertiesUI comes from your local copied @ui/diagram/swimlane entry. It takes laneOptions: { id, name }[], selected lane, size, optional minSize/maxSize, and emits laneChange, sizeChange and applySize. It owns neither the pool nor a command. The host derives applyDisabled/applyReason from session.swimlanes.availability(command) and executes lane-update on Apply. PrimeOne uses PrimeVue; Tailwind uses its themed HTML controls. The numeric draft is a local choice until Apply. Its saved source tracks the selected lane size, so divider edits and Undo/Redo update the field; unrelated selection and view changes do not replace a valid draft.

Lane collapse keeps a compact 32-unit strip and retains the expanded size. Descendants unmount and boundary connectors use shared collapsed proxies, with authored endpoints and route data retained for expansion. Lane content clips exclude headers. Layout changes do not imply obstacle routing.

Lane ordering moves content with its lane. Phase changes preserve a member's offset within its phase. Size changes preserve the content origin even for a rotated pool. Commands reject content that no longer fits, including derived nested extents and measured child bodies. Runtime measurement overflow clips without creating layout history.

#Transfer content and remove deliberately

From Reset, try Remove Intake (reject if occupied). Compare it with Remove Intake and relocate content. Transfer Request into Fulfillment or out to page space, then Undo. Use Fit if the placed task is outside the current view. Removing an already empty lane is a different outcome.

Loading Demo...

transfer takes ids and a destination laneId or parentId (null for page space), plus optional compatible pageId, layerId and phaseId. Without position, world geometry is rebased through parents. With position, the first normalized root is placed in destination-local coordinates and the cohort moves together, including independently reparented manual connector geometry. Egress clears phase membership. A partial cross-page move cannot leave a connector spanning pages. Use this API to enter/leave lanes rather than generic reparent.

Swimlane commandPurpose / explicit policy
createComplete pool node; creates the pool and lane records atomically.
updateOrientation, header settings or lane-only length.
lane-insert / phase-insertInsert a named, sized entry at an optional index.
lane-update / phase-updateChange name, size/minimum; lane updates also support collapse.
lane-order / phase-orderList every identity in that partition exactly once.
lane-removeNonempty lane requires same-pool relocateTo or explicit cascade. The last lane requires pool removal.
phase-removeAssigned content needs relocateTo or clearMembership; remaining geometry must still fit. Removing the last phase retains its extent as length.
removeExplicit cascade: true removes the pool subtree and incident connectors.
transferCompatible content ownership/placement, not independent lane-record movement.

Relocation keeps content and rejects a destination that cannot fit it. Cascade removes incident edges, but surviving navigation references cannot be left dangling. Inserting the first phase checks that existing lane content fits the new extent. Inspect the actual result/diagnostics rather than assuming every removal or transfer succeeds.

#Use the same commands for canvas gestures

Visible lane divider/reorder controls and selected-content transfer handles use begin, update, finish and cancel on the swimlane editor. A begin transaction ID is the ownership token; previews contain a portable proposed scene and affected IDs, not a durable model. One finish applies history. Identity/kind stay pinned; transfer destinations may change while the transferred IDs stay fixed.

Lane resize arrow keys change size by 5 units, or 20 with Shift. Lane reorder arrows move one position. Phase sizing and ordering use the supported command controls in this example. Escape, capture loss, blur, outgoing session destruction or stale geometry/policy release ownership. Invalid intermediate targets can lose the preview and recover at a valid target; invalid release cancels. Controlled stores propose one transaction and await host acknowledgement.

See Groups and containers, Pages and layers, Permissions and the Controlled State for host-owned proposal acceptance.