Vize

Kanban

Accessible, unstyled Kanban board: columns of cards with roving keyboard navigation and pointer + keyboard drag and drop (built on the shared drag-and-drop foundation), WIP limits, veto hooks, and announcements.

Package @vizejs/ui/kanban
Maturity stable
Own the source vize lib pull kanban
Requires context, drag-and-drop, id
Aliases task board, kanban board, swimlanes, card board
Covers WAI-ARIA drag-and-drop guidance, dnd-kit sortable board, Atlassian board

Usage

import { Kanban, KanbanCard, KanbanColumn } from "@vizejs/ui/kanban";

Or copy the source into your project with vize lib pull kanban (see Source Distribution).

API

Kanban<Card, ColumnId extends string>

Source: src/families/data/kanban/kanban.vue

Props

Prop Type Default Description
columns (required) readonly KanbanColumn<ColumnId>[] undefined Board columns in display order.
modelValue (required) KanbanBoard<Card, ColumnId> undefined Cards per column (v-model).
getCardKey (required) (card: Card) => string undefined Stable key per card.
getCardLabel (card: Card) => string undefined Card name for announcements; defaults to the rendered text.
canMove (card: Card, from: ColumnId, to: ColumnId) => boolean undefined Veto a move before it is offered as a drop target.
id string | null undefined Consumer-owned board id. null and undefined select a deterministic fallback.
dir "ltr" | "rtl" "ltr" Reading direction for Left/Right column navigation.
instructions string "Press Space or Enter to pick up the card. …" Keyboard instructions referenced by every card's aria-describedby.
announcements KanbanAnnouncements undefined Localized grab, move, drop, and cancel announcements.
ariaLabel string undefined Accessible name of the board.

Events

Event Payload Description
update:modelValue [value: KanbanBoard<Card, ColumnId>] Fired with the board after a move (supports v-model).
move [event: KanbanMoveEvent<Card, ColumnId>] Fired after a move commits with origin and destination.

Slots

Slot Slot props Description
column KanbanColumnSlotProps<Card, ColumnId> Column header contents. Defaults to the column title.
card KanbanCardSlotProps<Card, ColumnId> Card contents. Defaults to the card label or key.
empty { readonly column: KanbanColumn<ColumnId> } Rendered inside columns without cards.

Exposed

Member Type Description
element HTMLDivElement | null Rendered board element.
focusCard (cardKey?: string) => void Focus a card by key (or the current tab stop).
cancelDrag () => boolean Cancel an active drag.

KanbanCard

Source: src/families/data/kanban/kanban-card.vue

Props

Prop Type Default Description
cardKey (required) string undefined Stable card key.
columnId (required) string undefined Column the card is in.
index (required) number undefined Zero-based index, published as aria-posinset (one-based).
label string undefined Name used by drag announcements; defaults to the rendered text.
disabled boolean false Keep the card focusable but not draggable.

Slots

Slot Slot props Description
default { readonly dragging: boolean } Card contents. Receives the drag state.

KanbanColumn

Source: src/families/data/kanban/kanban-column.vue

Props

Prop Type Default Description
columnId (required) string undefined Column id.
title (required) string undefined Column title and accessible name.
count number 0 Number of cards, published as aria-setsize context and data-count.
limit number undefined WIP limit, published as data-limit.
disabled boolean false Refuse drops.

Slots

Slot Slot props Description
header — Column header contents.
default — Cards (KanbanCard elements).

Behavior

@vizejs/ui/kanban renders a board of labelled columns (kanban-column.vue) holding focusable cards (kanban-card.vue); kanban.vue is the generic root (Card, ColumnId). Pointer and keyboard moves use the shared drag-and-drop foundation (cards are sources and "before" targets; column lists are "end" targets). Every row is proven by the named test in kanban.test.ts or kanban-ssr.test.ts.

# State Input Outcome Proven by
K1 any render labelled board, role="group" columns named by their header, lists of listitem cards described by instructions renders labelled column groups with lists of focusable cards and instructions
K2 card focus arrows, Home/End roving focus moves within a column and across columns (index clamped, empty columns skipped) arrow keys move the roving focus within and across columns
K3 card focus Space, arrows, Enter keyboard drag cycles valid targets, drops into another column, emits move + update:modelValue, keeps focus keyboard drag moves a card into another column and keeps focus on it
K4 keyboard drag Escape cancels without moving Escape cancels a keyboard drag without moving
K5 limits and vetoes keyboard drag full (limit) and disabled columns and canMove vetoes are never offered as targets WIP limits, disabled columns, and canMove veto drop targets
K6 pointer drag release over a card's lower half the drop edge is published and the card lands after it dropping on a card's bottom edge inserts after it
K7 custom boards import KanbanColumn and KanbanCard parts are exported column and card parts are exported for custom boards
K8 SSR two requests + hydrate byte-identical markup with one tab stop and no drag state; warning-free hydration renders identical board markup across SSR requests and hydrates cleanly