Kanban

Cards in columns that people move by dragging, with the keyboard, or with screen reader actions.
Experimental
Web
iOS
Android
@advui/data
Source

Sprint board

To do
Add partners to the map legend
Collect the Chin State sheetsThree townships are still missing.
Update the Kobo form
In progress
Clean the September dataMerge duplicate rows and fix the township codes.
Review
Dashboard filters
Done
No cards
Press Space to pick the card up. Then the arrow keys move it, Space drops it and Escape puts it back.

Installation

pnpm
pnpm add @advui/data
npm
npm install @advui/data

Usage

import { Kanban } from '@advui/data'

<Kanban
  aria-label="Sprint board"
  defaultValue={[
    { id: 'todo', title: 'To do', items: [{ id: 'a', title: 'Write the report' }] },
    { id: 'done', title: 'Done', items: [] },
  ]}
  onItemMove={(move) => save(move)}
/>

Examples

Custom cards

`renderItem` draws a priority and an owner; a closed request is `disabled`.
New
Request from Magway
High
Request from Sagaing
Low
Assigned
Request from Kachin
Medium
Closed
Request from Shan
Low
Press Space to pick the card up. Then the arrow keys move it, Space drops it and Escape puts it back.
Drag a request, or press Space on one.

API reference

Kanban

Takes size props such as `width`; the board scrolls sideways inside it.
PropTypeDefaultDescription
valueKanbanColumn<T>[]—The columns and their cards: `{ id, title, items }`.
defaultValueKanbanColumn<T>[]—Starting `value` when uncontrolled.
onValueChange(columns: KanbanColumn<T>[]) => void—Called with the columns after a card moves.
onItemMove(move: KanbanMove) => void—`{ itemId, from, to }` after a move, each `{ columnId, index }`: save it here.
onItemPress(item: T) => void—A card was pressed, or Enter pressed on it: open it here.
onItemDragStart(item: T) => void—A card was picked up. On iOS and Android, stop a scroll view around the board that is not a ScrollArea or AppShell here (`scrollEnabled={false}`).
onItemDragEnd(item: T) => void—A picked-up card was dropped or put back.
renderItem(item: T) => ReactNode—Draws a card’s content; the card around it moves. Default: the title and description. Keep buttons and links out of it.
columnWidthSizeTokens | number'72'Width of each column.
aria-labelstring—Names the board for screen readers. Recommended.
labelsPartial<KanbanLabels>—The keyboard instructions, announcements (`pickedUp`, `moved`, `dropped`, `cancelled`) and action names, for other languages.

KanbanItem

A card. Extend it with your own fields and draw them with `renderItem`.
PropTypeDefaultDescription
id requiredstring—Unique key.
title requiredstring—Shown by default, and used in announcements.
descriptionstring—Shown under the title by default.
disabledboolean—Stays where it is: it cannot be picked up.

moveItem(columns, itemId, columnId, index)

The columns with one card moved: apply a `KanbanMove` from a server, or move cards from your own controls.

findItem(columns, itemId)

A card’s column and index, or null.

Accessibility

  • The board is a named region that scrolls sideways; each column is a list named with its title and count (a named group while empty), and each card a listitem holding a button (web). A default card is named by its title and described by its description; a renderItem card is named by its content.
  • Keyboard: Space picks a card up, the arrow keys move it within and between columns, and Space or Enter drops it; Escape, or moving focus away, puts it back. Each card is described by these instructions.
  • Each step is announced through an assertive live region: “Picked up Update the Kobo form. To do, position 3 of 3.”, then the new place, then where it was dropped.
  • A moved card keeps focus, even when it mounts again in another column.
  • On iOS and Android each card has screen reader actions, Move up, Move down and Move to the next column’s name, and the move is announced. Swipe up or down on a card to choose one.
Keyboard interactions
KeyAction
TabMoves between cards.
SpacePicks a card up, or drops it.
Arrow Up / Arrow DownMoves the card within its column.
Arrow Left / Arrow RightMoves the card to the next column.
EnterDrops a picked-up card, or presses a card when `onItemPress` is set.
EscapePuts the card back where it was.

Platform notes

Web
A mouse drags once it moves; a finger after holding still for a moment, so a swipe still scrolls the board. The board scrolls sideways near its edges while dragging.
iOS
A long press picks a card up and the finger drags it. The board and the ScrollArea or AppShell around it stop scrolling until the finger lifts, so a quick first move drags the card. Stop any other scroll view around the board in onItemDragStart. Not yet checked on a device.
Android
Same as iOS. Checked on a phone before scroll views stopped during a drag: a quick first move scrolled the screen and cancelled the drag.
Since v0.14.0Last updated Nov 2, 2026Edit this page on GitHub