Your First Kanban Board
Create a small working board before adding rules, forms or remote data. The example uses the same task cards throughout these guides.
Your first board
Four tasks move through To do, In progress and Done.
Try it: Move the research card, or double-click a card to edit it.
What to notice: Moving a card changes its status; the board keeps the same four tasks.
TypeScript source
Install the packages from Getting Started, then use this source in your app.
import { defineCustomElements } from '@revolist/revogrid/loader';import { KanbanPlugin, type KanbanConfig } from '@revolist/kanban';import '@revolist/revogrid-pro/styles.css';import '@revolist/kanban/styles.css';
export interface WorkCard { id: string; title: string; status: string; order: number; description?: string; team?: string; owner?: string; priority?: string; tags?: string[]; progress?: number; startDate?: string; endDate?: string;}export const demoCards: WorkCard[] = [ { id: 'task-1', title: 'Research customer needs', description: 'Collect feedback for the next release.', status: 'todo', team: 'product', owner: 'Ana', priority: 'normal', order: 1000 }, { id: 'task-2', title: 'Build onboarding', description: 'Make the first session useful.', status: 'doing', team: 'product', owner: 'Mia', priority: 'high', order: 1000 }, { id: 'task-3', title: 'Improve API errors', description: 'Return actionable validation messages.', status: 'todo', team: 'platform', owner: 'Rui', priority: 'normal', order: 2000 }, { id: 'task-4', title: 'Release checklist', description: 'Ready for the next deployment.', status: 'done', team: 'platform', owner: 'Sam', priority: 'normal', order: 1000 },];export const boardConfig: KanbanConfig<WorkCard> = { columns: [{ prop: 'todo', name: 'To do', size: 210 }, { prop: 'doing', name: 'In progress', size: 210 }, { prop: 'done', name: 'Done', size: 210 }], card: { titleField: 'title' }, cardRowHeight: 88, addCard: false, swimlaneColumn: false,};
export async function configureBoard( grid: HTMLRevoGridElement, config: KanbanConfig<WorkCard> = boardConfig, cards: readonly WorkCard[] = demoCards, extraPlugins: HTMLRevoGridElement['plugins'] = [],) { await defineCustomElements(); grid.plugins = [KanbanPlugin, ...extraPlugins]; // The packaged editor and history install automatically. grid.columns = [{ prop: 'title', name: 'Title' }, { prop: 'status', name: 'Status' }, { prop: 'owner', name: 'Owner' }]; // Cached remote data can hydrate immediately: finish initial grid setup first. grid.kanban = config.remote ? { ...config, remote: false } : config; grid.source = cards.map(card => ({ ...card })); await grid.componentOnReady(); const plugins = await grid.getPlugins(); const kanban = plugins.find((plugin): plugin is KanbanPlugin<WorkCard> => plugin instanceof KanbanPlugin); if (!kanban) throw new Error('Kanban could not start.'); if (config.remote) grid.kanban = config; return kanban;}
// Give your container a width and mount once after it exists in the DOM.export async function createKanbanBoard(container: HTMLElement) { await defineCustomElements(); const grid = document.createElement('revo-grid'); grid.style.cssText = 'display:block;width:100%;height:400px'; container.append(grid); try { const kanban = await configureBoard(grid); return { grid, kanban, destroy() { grid.remove(); } }; } catch (error) { grid.remove(); throw error; }}Try it: move a card from To do to In progress, then Reset. Double-click a card to open the packaged editor.
Install
Section titled “Install”pnpm add @revolist/revogrid @revolist/revogrid-pro @revolist/kanbanimport '@revolist/revogrid-pro/dist/revogrid-pro.css';import '@revolist/kanban/styles.css';Run the example source
Section titled “Run the example source”Open the example’s TypeScript source and download first-board.ts. The live example imports the same source; it includes the card data, field mapping, plugin registration and cleanup.
Call its exported helper from your browser application:
import { createKanbanBoard, boardConfig } from './first-board';
const host = document.createElement('div');document.body.append(host);const board = await createKanbanBoard(host);const { grid, kanban } = board;const config = boardConfig; // The plain configuration used in later recipes.// On application cleanup: board.destroy();The helper returns the grid and public Kanban plugin. Replace demoCards with your records, then map different field names in Card Data and Field Mapping.
Alternative: inline single-card TypeScript setup
Minimal setup
Section titled “Minimal setup”import { defineCustomElements } from '@revolist/revogrid/loader';import { KanbanPlugin, type KanbanConfig } from '@revolist/kanban';import '@revolist/revogrid-pro/styles.css';import '@revolist/kanban/styles.css';
defineCustomElements();await customElements.whenDefined('revo-grid');
const kanban: KanbanConfig = { columns: [ { prop: 'todo', name: 'To do' }, { prop: 'doing', name: 'In progress', wipLimit: 3 }, { prop: 'done', name: 'Done' }, ], card: { titleField: 'title', descriptionField: 'description' },};
const grid = document.createElement('revo-grid');grid.style.cssText = 'display:block;height:600px;width:100%';grid.plugins = [KanbanPlugin];grid.kanban = kanban;document.body.append(grid);grid.source = [ { id: 'card-1', title: 'First card', status: 'todo', order: 1000 },];
// Call when the host view unmounts.export const destroy = () => grid.remove();The packaged editor is installed automatically. Double-click a card to edit it;
set grid.kanbanCardEditorDialog = false only when supplying your own editor.
Add packaged controls
Section titled “Add packaged controls”Install KanbanToolbarPlugin alongside KanbanPlugin for
card actions, search, field filters, undo/redo and board/table switching. The toolbar
uses the same editor, canonical cards and persistence adapter as other interactions.
React integration
React starter
Section titled “React starter”Add react, react-dom, their TypeScript types and @revolist/react-datagrid.
Include the following JSX augmentation to type the kanban property in your
application.
import { useMemo } from 'react';import { RevoGrid } from '@revolist/react-datagrid';import { KanbanPlugin, type KanbanConfig } from '@revolist/kanban';import '@revolist/revogrid-pro/styles.css';import '@revolist/kanban/styles.css';
declare module '@revolist/revogrid' { namespace JSX { interface RevoGrid { kanban?: KanbanConfig<any> | false; } }}
type Card = { id: string; title: string; status: string; order: number };
export default function Board({ rows }: { rows: Card[] }) { const plugins = useMemo(() => [KanbanPlugin], []); const kanban = useMemo<KanbanConfig>(() => ({ columns: [{ prop: 'todo', name: 'To do' }, { prop: 'done', name: 'Done' }], card: { titleField: 'title' }, }), []); return <RevoGrid style={{ height: '600px', width: '100%' }} plugins={plugins} kanban={kanban} source={rows} />;}Pass rows={[]} for an empty board; replace rows when application data arrives.
React owns mounting and unmounting the grid. The standalone
Kanban showcase also includes Vue and Angular
examples.
The default fields are id, status, and order. Configure idField, columnField, or orderField when your application uses other names.
columns is optional so Kanban can be enabled before workflow metadata or data
loads. An empty configuration and empty source render a stable empty board. If
cards arrive before columns, they remain visible in the managed Unmapped
column until the workflow configuration is supplied.
Continue with Cards, Swimlanes and WIP and the Toolbar.
Common setup problems
Section titled “Common setup problems”- Give the grid an explicit height and import both Pro and Kanban styles.
- Put application cards in
grid.source, not the projected board rows. - Match each card status to a workflow
prop; labels may be different. - Keep card IDs unique and stable. Invalid IDs remain visible but cannot move.
- Remove the grid when your view unmounts so listeners and loading owners are released.
Next steps
Section titled “Next steps”Next, learn card fields, columns and swimlanes. See the Kanban API for exact types.