Search and Filters
Search narrows the visible board so users can focus on a title, owner or priority. Hidden cards remain in the source data and continue to count toward work-in-progress limits.
Find the right work
Filters change which cards are visible without deleting source cards.
Try it: Show only high-priority work, search for research, then clear the filter.
What to notice: Clearing filters restores all four source cards.
TypeScript source
Install the packages from Getting Started, then use this source in your app.
import type { KanbanPlugin } from '@revolist/kanban';import type { WorkCard } from './first-board';
export function showHighPriority(kanban: KanbanPlugin<WorkCard>) { kanban.setFilter({ predicate: card => card.priority === 'high' });}export function searchResearch(kanban: KanbanPlugin<WorkCard>) { kanban.setFilter({ query: 'research', fields: ['title'] });}export function clearFilters(kanban: KanbanPlugin<WorkCard>) { kanban.setFilter(); }
// An app-owned snapshot of serializable data, not a Kanban remote-store API.export function captureBoard(kanban: KanbanPlugin<WorkCard>) { return { cards: kanban.getCards().map(card => ({ ...card })), columns: [...kanban.getColumnOrder()], collapsed: [...kanban.getCollapsedColumnProps()], selected: [...kanban.getSelectedCardIds()] };}export async function restoreBoard(grid: HTMLRevoGridElement, kanban: KanbanPlugin<WorkCard>, saved: ReturnType<typeof captureBoard>) { grid.source = saved.cards.map(card => ({ ...card })); await new Promise<void>(resolve => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))); kanban.setColumnOrder(saved.columns); for (const prop of kanban.getColumnOrder()) kanban.setColumnCollapsed(prop, saved.collapsed.includes(prop)); kanban.setSelectedCardIds(saved.selected);}// Persist JSON.stringify(captureBoard(kanban)) in your application's storage.// Restore only data validated by your application; the live example stays in memory.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: choose High priority only, then Find research, then Clear filters. Each action replaces the previous filter; all four cards return in their original positions when cleared.
Filtering and search
Section titled “Filtering and search”Core RevoGrid filters are evaluated against canonical cards and the host’s captured table columns. Kanban then composes its lightweight search and predicate:
grid.kanban = { ...config, filter: { query: searchInput.value, fields: ['title', 'owner', 'labels'], predicate: (card) => !card.archived, },};A card must pass all three layers: RevoGrid filters, query matching, and the predicate. Search defaults to the configured card title field.
Header counts expose visible and total cards when filters differ. WIP limits always count all canonical cards.
Use only the controls you need
Section titled “Use only the controls you need”grid.kanbanToolbar = { actions: [], search: true, workflowFilter: true, viewSwitcher: false, filters: [{ id: 'priority', field: 'priority', label: 'Priority' }],};Install KanbanToolbarPlugin to render these controls. Set actions: [] when the toolbar should filter rather than edit the board.
Server-side data
Section titled “Server-side data”Kanban filters are local projections of the cards available to the board. They are not a server query over records that have not loaded. Apply server filters in your application’s loader and replace its dataset/query identity when that dataset changes; see remote loading.
Next steps
Section titled “Next steps”Continue with undo and redo, WIP counts and toolbar configuration. See the Kanban API for exact types and signatures.