Data display
Kanban board
A Kanban board that a keyboard can actually use.
Import
import { KanbanBoard } from '@the_viveksingh/vivek-ui'A sprint board you can drive from the keyboard
HTML5 drag-and-drop has no keyboard equivalent at all, which is why nearly every Kanban board is mouse-only. This has two complete input paths: dragging, and a pick-up / move / drop model announced through a live region.
Drag with a mouse, or Tab to a card and press Enter to pick it up — then arrow keys to move, Enter to drop, Escape to cancel. Every move is announced to a screen reader.
- Audit the colour paletteP3
Check every token pair for contrast.
Press Enter or Space to pick this card up. - Write the migration noteP2Press Enter or Space to pick this card up.
- Ship the Kanban boardP1
Keyboard path is the hard part.
Press Enter or Space to pick this card up.
- FileTree keyboard modelP1Press Enter or Space to pick this card up.
- VirtualListPress Enter or Space to pick this card up.
const [columns, setColumns] = useState(initial)
<KanbanBoard
columns={columns}
label="Sprint board"
// Nothing is mutated for you - the board reports the intended move.
onMove={({ cardId, fromColumnId, toColumnId, toIndex }) =>
setColumns((current) => applyMove(current, cardId, fromColumnId, toColumnId, toIndex))
}
/>
// Columns carry an optional work-in-progress limit, which blocks drops when reached:
const initial = [
{ id: 'backlog', title: 'Backlog', cards: [...] },
{ id: 'doing', title: 'In progress', cards: [...], limit: 2 },
{ id: 'done', title: 'Done', cards: [] },
]Props
Generated from the package's own type declarations, so this table cannot drift from the code.
| Prop | Type | Default | Description |
|---|---|---|---|
columns required | readonly KanbanColumn[] | — | — |
label required | string | — | Required. A board with no accessible name is one more unlabelled region. |
onMove | (move: KanbanMove) => void | — | Nothing is moved for you — apply this to your own state. |
renderCard | (card: KanbanCard, column: KanbanColumn) => ReactNode | — | Rendered instead of the default card body. |
className | string | — | — |
Rendering
KanbanBoard declares 'use client' because it needs state, effects or event handlers. Importing it into a Server Component creates a client boundary at this component — everything above it stays on the server.