Kanban
Kanban
The Kanban category provides a complete board UI with drag-and-drop between columns, responsive mobile column switching, and optional deep integration with useXCrud for automatic data management. Cards are fully customizable via slots.
Components
<XAKanban />
The root board component. Accepts a columns definition array and an items array (or a useXCrud instance via crud). Groups items into columns by the groupBy field key. On desktop, renders all columns side by side with horizontal scroll. On mobile (when responsive is true), renders a column selector dropdown followed by the active column.
<XAKanban
v-model="items"
:columns="[
{ id: 'todo', label: 'To Do', icon: 'i-lucide-circle', color: 'neutral' },
{ id: 'in_progress', label: 'In Progress', icon: 'i-lucide-loader', color: 'warning', limit: 5 },
{ id: 'done', label: 'Done', icon: 'i-lucide-check-circle', color: 'success' },
]"
:items="tasks"
group-by="status"
title="Project Board"
:config="{
draggable: true,
columnWidth: '320px',
showColumnCounts: true,
allowAdd: true,
allowDelete: false,
cardConfig: {
showAvatar: true,
showDueDate: true,
showPriority: true,
showTags: true,
},
}"
:responsive="true"
@card-move="handleCardMove"
@card-click="openTaskDetail"
@column-add="openCreateTask"
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | Array | undefined | Items array with two-way binding (v-model) |
columns | Array | required | Column definitions — each must have at minimum id and label |
items | Array | [] | Items to distribute across columns |
crud | Object | null | useXCrud instance for automatic data management |
groupBy | String | 'columnId' | Item field used to assign items to columns |
idKey | String | 'id' | Item field used as the unique identifier |
title | String | '' | Board heading |
description | String | '' | Board subheading |
responsive | Boolean | true | Show mobile column-switcher UI on small screens |
defaultColumn | String | Number | first column | Initial active column for mobile view |
config | Object | see below | Board-level configuration object |
endpoint | String | null | API endpoint (used with crud mode) |
loading | Boolean | false | Show loading state |
error | Error | String | Object | null | Show error state |
config defaults:
{
draggable: true,
cardConfig: {
showAvatar: true,
showDueDate: true,
showPriority: true,
showTags: true,
showAssignee: true,
compact: false,
},
columnWidth: '320px',
columnMinWidth: '280px',
columnGap: '4',
showColumnCounts: true,
showColumnLimits: true,
allowAdd: false,
allowDelete: false,
}
Column object shape:
| Field | Type | Description |
|---|---|---|
id | string | number | Unique column identifier (matched against groupBy field) |
label | string | Column heading |
icon | string? | Lucide icon name |
color | string? | Nuxt UI color for badge and icon |
limit | number? | Max items — shows warning footer when reached, blocks drops |
droppable | boolean? | Whether items can be dropped into this column (default true) |
Emits
| Event | Payload | Description |
|---|---|---|
update:modelValue | Array | Updated items after a drag-and-drop move |
card-move | { item, fromColumnId, toColumnId } | Card moved between columns |
card-click | item | Card clicked |
card-delete | item | Card delete button clicked |
column-add | column | Column add button clicked |
retry | — | Retry button clicked in error state |
Slots
| Slot | Props | Description |
|---|---|---|
header | { columns, items } | Replace the default board header |
header-actions | — | Extra content in the default header, right side |
card | { item, isDragging } | Custom card rendering |
card-actions | { item } | Extra actions slot passed into each card |
empty | { column, items } | Custom empty state per column |
column-header-actions | { column, items } | Extra actions in each column header |
<XAKanbanColumn />
A single board column. Handles drag-over highlighting, item count badge, optional limit warning footer, and an add button. Passes drag events up to XAKanban.
<XAKanbanColumn
:column="{ id: 'todo', label: 'To Do', color: 'neutral' }"
:items="todoItems"
:draggable="true"
:droppable="true"
:show-count="true"
:show-limit="true"
:allow-add="true"
:allow-delete="false"
column-width="320px"
column-min-width="280px"
:card-config="{ showAvatar: true, showDueDate: true, showPriority: true }"
@add="openCreate"
@card-click="openDetail"
@drop="handleDrop"
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
column | Object | required | Column definition object |
items | Array | [] | Items in this column |
draggable | Boolean | true | Allow cards to be dragged |
droppable | Boolean | true | Allow cards to be dropped here |
cardConfig | Object | { showAvatar, showDueDate, showPriority, showTags, showAssignee: true, compact: false } | Card display options passed to each XAKanbanCard |
columnWidth | String | '320px' | Column CSS width |
columnMinWidth | String | '280px' | Column CSS min-width |
showCount | Boolean | true | Show item count badge in header |
showLimit | Boolean | true | Show limit warning footer |
allowAdd | Boolean | false | Show add button in column header |
allowDelete | Boolean | false | Show delete button on each card |
Emits
add, card-click, card-delete, drop
<XAKanbanCard />
A draggable card article. Default slot renders title, description, priority icon, tags, assignee, and due date from the item object. Accepts a default slot for fully custom content.
<XAKanbanCard
:item="task"
:draggable="true"
:show-avatar="true"
:show-due-date="true"
:show-priority="true"
:show-tags="true"
:show-assignee="true"
:compact="false"
:allow-delete="false"
@click="openTask"
@delete="deleteTask"
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
item | Object | required | Item data object |
draggable | Boolean | true | Enable HTML drag API |
showAvatar | Boolean | true | Show assignee avatar |
showDueDate | Boolean | true | Show due date |
showPriority | Boolean | true | Show priority icon |
showTags | Boolean | true | Show tag badges |
showAssignee | Boolean | true | Show assignee name |
compact | Boolean | false | Compact padding and truncated description |
allowDelete | Boolean | false | Show delete button on hover |
Emits
click, delete, dragstart, dragend
Expected item shape:
{
id: string | number
title: string
description?: string
priority?: 'high' | 'medium' | 'low'
tags?: string[]
dueDate?: string | Date
assignee?: { name: string, avatar?: string }
[groupByKey]: string | number // e.g., columnId or status
}
Slots
| Slot | Props | Description |
|---|---|---|
default | { item, isDragging } | Replace the entire card body |
actions | { item } | Replace the hover actions area |
AI Context
category: Kanban
package: "@xenterprises/nuxt-x-app"
components:
- XAKanban
- XAKanbanColumn
- XAKanbanCard
use-when: >
Building workflow boards, project task management, pipeline views, or any
UI where items move between discrete status stages. Use XAKanban as the
top-level component and customize with slots as needed.
key-patterns:
- columns array defines board structure; items are grouped by the groupBy field
- config object controls all display and behavior options in one place
- Use the card slot for fully custom card rendering
- column.limit enforces WIP limits — drops are blocked when limit is reached
- responsive: true gives a mobile-friendly column selector automatically
- card-move event fires with fromColumnId / toColumnId for API updates
item-shape: "{ id, title, description?, priority?, tags?, dueDate?, assignee?, [groupByKey] }"
column-shape: "{ id, label, icon?, color?, limit?, droppable? }"
