TaskBoard - Architecture
Understand the Vue TaskBoard runtime, data model, compound parts, workflow rules, and customization boundaries.
#Usage
import { TaskBoard } from '@primeui/vue-taskboard';<TaskBoard.Root v-model:tasks="items" :columns="columns" :swimlanes="swimlanes" :column-groups="columnGroups" data-key="id" column-field="stage" swimlane-field="teamId" selection-mode="multiple" column-reorderable context-menu virtual-scroll>
<TaskBoard.Header />
<TaskBoard.Content>
<TaskBoard.SwimlaneColumnHeader />
<TaskBoard.SwimlaneHeader />
<TaskBoard.Column v-for="column in columns" :key="column.id" :value="column.id" :label="column.label">
<TaskBoard.ColumnHeader />
<TaskBoard.ColumnContent>
<TaskBoard.Card>
<TaskBoard.CardHeader />
<TaskBoard.CardContent />
<TaskBoard.CardFooter />
</TaskBoard.Card>
<TaskBoard.ColumnEmpty />
</TaskBoard.ColumnContent>
<TaskBoard.ColumnFooter />
</TaskBoard.Column>
</TaskBoard.Content>
<TaskBoard.DropIndicator />
<TaskBoard.DragPreview />
<TaskBoard.DragConfirm />
<TaskBoard.Loading />
</TaskBoard.Root>The root owns data access, state, interaction, events, methods, and accessibility wiring. The tree above is an anatomy map: it shows the public scopes and outlets TaskBoard can invoke. A real board should declare only the columns, swimlane parts, drag surfaces, and custom slots it uses.
#Runtime Model
TaskBoard has two layers.
| Layer | Owned by | What it controls |
|---|---|---|
| Runtime | @primeui/vue-taskboard | Data access, selection, drag, reorder, history, workflow checks, keyboard handling, print, scrolling, and contexts. |
| Visual UI | The application | Toolbar controls, card layout, column header content, menu overlays, dialog bodies, swimlane labels, and styling. |
PrimeOne and Tailwind UI parts are editable starter components copied into the app. They are not required runtime dependencies. Applications can also write custom parts that consume TaskBoard slot props or context hooks. Filtering, sorting, dialogs, menus, and persistence stay in the application so the board can render product records without forcing a task schema.
#First Board
Start with stable item ids, column metadata, TaskBoard.Root, TaskBoard.Content, one TaskBoard.Column per status, a column header, and a card outlet.
#Data Model
TaskBoard reads plain application data. Items drive cards and move payloads. Columns define the workflow lanes. Swimlanes define grouped rows when the product needs a second dimension such as team, account, region, priority, release, or owner group. The root does not require a title, description, priority, task type, label array, or editor shape.
import type { TaskBoardColumn, TaskBoardSwimlane, TaskBoardItem } from '@primeui/vue-taskboard';
const columns: TaskBoardColumn[] = [
{ id: 'backlog', label: 'Backlog', statusType: 'todo', order: 0 },
{ id: 'active', label: 'Active', statusType: 'in-progress', wipLimit: 6, order: 1 },
{ id: 'done', label: 'Done', statusType: 'done', locked: true, order: 2 }
];
const swimlanes: TaskBoardSwimlane[] = [
{ id: 'growth-team', label: 'Growth Team', order: 0 },
{ id: 'platform-team', label: 'Platform Team', order: 1 }
];
const items = ref<TaskBoardItem[]>([
{
id: 'INIT-1042',
stage: 'backlog',
teamId: 'growth-team',
name: 'Trial conversion review',
account: 'Northstar',
risk: 'medium',
labels: ['activation', 'billing'],
order: 0
}
]);Use top-level fields when TaskBoard needs to read the value configured by data-key, column-field, or swimlane-field. Keep product metadata on the item record for custom cards, app-owned filters, menus, export flows, or workflow checks.
| Field | Use |
|---|---|
data-key | Root prop that names the stable item id field used for rendering, selection, drag, and exposed methods. |
column-field | Root prop that names the item field storing the current column value. |
swimlane-field | Root prop that names the item field storing the current swimlane value. |
TaskBoardColumn.id | Column identity used by root props, rendered columns, move payloads, and column methods. |
TaskBoardColumn.label | Accessible and visible column name. |
TaskBoardSwimlane.id | Swimlane identity used by row rendering, collapse state, and lane-aware moves. |
order | App-owned ordering field that demos and products can use for sorted presentation. |
TaskBoardTask is still exported for older code and for products that want the optional fields used by the included card UI parts. New applications should start from TaskBoardItem and shape records around their domain.
#State Ownership
Use v-model:tasks when TaskBoard can replace the bound item array after create, update, delete, move, and reorder actions.
<TaskBoard.Root v-model:tasks="tasks" data-key="id" column-field="columnId">
<!-- TaskBoard parts -->
</TaskBoard.Root>Use :items when a store, API cache, or parent component owns every mutation. In that mode, listen to emitted events and update the external source yourself.
<TaskBoard.Root :items="tasks" data-key="id" column-field="columnId" @card-move="onCardMove" @card-update="onCardUpdate">
<!-- TaskBoard parts -->
</TaskBoard.Root>The emitted move payload uses indexes relative to the active column and swimlane cell. That keeps normal boards, swimlane boards, externally queried boards, and virtualized boards aligned with the visual drop position.
Search, filtering, and sorting are part of that external data layer. Derive the visible item array in app code, normalize order per column or swimlane cell, and pass the result to TaskBoard. The board keeps keyboard focus, drag targets, virtual-scroll anchors, and move payloads aligned with the array it receives.
#Layout Model
Columns can come from the columns prop or from explicit TaskBoard.Column children. When both are present, the columns prop is the data source and the rendered children provide the visible outlets.
| Layout | Use it when | Documentation |
|---|---|---|
| Columns | A workflow status owns each lane. | Columns |
| Swimlanes | Work needs a second grouping dimension. | Swimlanes |
| Column groups | Related columns need grouped headers above the board. | Column Groups |
| Virtual scroll | A column or swimlane board can contain large task collections. | Virtual Scroll |
Swimlane moves update both the column field and the swimlane field when the card crosses rows. Virtual scroll keeps mounted ranges anchored by task or swimlane identity instead of resetting scroll position after updates.
#Compound Anatomy
TaskBoard is compound by default. The runtime wrappers stay in the tree so selection, focus, drag, keyboard, collapse, data attributes, and accessibility remain stable while the app owns the visible UI.
| Part | Purpose | Typical child |
|---|---|---|
TaskBoard.Root | Data access, state, events, methods, feature flags, keyboard, drag, selection, and context. | All other parts |
TaskBoard.Header | Board-level surface for search controls, filters, export, print, role controls, or create actions. | Product toolbar |
TaskBoard.Content | Column, swimlane, group-header, scroll, and virtual-scroll layout. | Column and swimlane parts |
TaskBoard.Column | Registers one workflow column and its collapse or reorder state. | Header, content, footer |
TaskBoard.ColumnHeader | Column label, count, collapse button, locked state, and optional header-surface reorder. | Copied or custom header UI |
TaskBoard.ColumnContent | Iterates visible cards for a column or swimlane cell. | Card and empty-state parts |
TaskBoard.ColumnEmpty | Empty-state outlet when the visible column or swimlane cell has no cards. | Empty copy or action |
TaskBoard.ColumnFooter | Footer surface for add buttons, totals, or column controls. | Footer controls |
TaskBoard.Card | Card wrapper, context, focus target, selection state, drag state, and data attributes. | Product card body |
TaskBoard.CardHeader | Card header outlet inside the card context. | Title or metadata |
TaskBoard.CardContent | Main card body outlet inside the card context. | Product fields |
TaskBoard.CardFooter | Card footer outlet inside the card context. | Status, progress, actions |
TaskBoard.DragPreview | Drag feedback for one card or a selected group. | Preview markup |
TaskBoard.DragConfirm | Confirmation surface for guarded workflow moves. | Confirmation dialog |
TaskBoard.DropIndicator | Custom insertion marker while TaskBoard owns hit testing and target indexes. | Marker line or placeholder |
TaskBoard.SwimlaneHeader | Left-side row header for grouped boards. | Row label or summary |
TaskBoard.SwimlaneColumnHeader | Column labels repeated in the swimlane grid. | Compact column labels |
TaskBoard.Loading | Loading surface when async state needs a board-owned location. | Loading indicator |
#Feature Surface
Add features after the data model and layout are clear.
| Feature | Default or opt-in state | Solves |
|---|---|---|
| Drag and drop | Enabled unless draggable or features.dragDrop disables it. | Card move and reorder workflows. |
| Column collapse | Enabled unless column-collapsible or features.columnCollapse disables it. | Compact boards with hidden lanes. |
| Column reorder | Opt in with column-reorderable; features.columnReorder can disable it. | User-controlled lane order with locked-column boundaries. |
| Card selection | Starts at selection-mode="none"; use single or multiple to enable it. | Bulk actions and multi-card drag. |
| Context menu | Opt in with context-menu. | Emits @card-context-menu so the app can open its own menu. |
| WIP and transition rules | Driven by column metadata and workflow feature flags. | Guarded moves, required fields, WIP limits, and confirmations. |
| Virtual scroll | Opt in with virtual-scroll. | Large boards without mounting every card or swimlane row. |
#Events and Methods
TaskBoard emits typed payloads for user actions such as card move, card reorder, card click, card activation, selection change, column collapse, column reorder, swimlane collapse, context menu, blocked drop, and drag lifecycle.
Right-click menus are event-driven. Set context-menu, listen to @card-context-menu, then open a PrimeVue ContextMenu, popover, drawer, or product-specific menu from the emitted { card, column, position, jsEvent } payload. Card detail and edit flows work the same way: listen to @card-click, @card-dblclick, or @card-activate, then open the dialog, route, drawer, or inspector your product owns.
Use exposed methods when a toolbar or external control needs to act on the board:
import type { TaskBoardExpose } from '@primeui/vue-taskboard';
const board = ref<TaskBoardExpose | null>(null);
board.value?.scrollToCard('JOB-1042');
board.value?.setSelectedCards(['JOB-1042', 'JOB-1043']);
board.value?.print();See Events and API for the full contract.
#Styling Boundary
Runtime styles keep the board usable: layout, scroll, drag states, selection, focus, density, RTL, print, and virtual-scroll spacing. UI parts decide how cards, headers, swimlane labels, and toolbar controls look. Product overlays such as context menus and dialogs are normal app components wired from TaskBoard events.
Use copied UI parts first when the product can follow PrimeOne or Tailwind styling. Replace individual parts when the card body, header metadata, swimlane label, add action, or drop indicator needs product-specific markup. Keep TaskBoard.Card, TaskBoard.ColumnHeader, TaskBoard.SwimlaneHeader, and the other runtime wrappers around custom children so data attributes, focus handling, keyboard behavior, drag hit testing, and collapse semantics stay intact.
#Accessibility and Performance
TaskBoard manages board-level keyboard handling, focus targets, selection state, live announcements, collapsed column state, and interactive drag state. Nested buttons, inputs, links, and other interactive elements keep their own keyboard behavior instead of being intercepted by board shortcuts.
Rendering is indexed by column and swimlane cell. Virtual scroll anchors by task or swimlane identity, then clamps when app-side queries, deletes, moves, or sort changes make the old scroll range impossible. Use Performance when planning large boards.