AI
Kanban logov1.0.0

Board & Columns Architecture

Understand the underlying data model, event flows, and spatial drag mechanics of Nofinite Kanban.

typescript
// Framework-Agnostic Core
import { 
  createKanbanBoard, 
  type KanbanColumn, 
  type KanbanItem,
  type CardMoveEvent,
  type ColumnMoveEvent 
} from '@nofinite/kanban';

// React Adapter
import { Kanban, type KanbanColumnProps } from '@nofinite/kanban/react';

Data Model

The data structures are pure, framework-agnostic TypeScript interfaces shared across Vanilla JS, Vue, Svelte, and React:

KanbanColumn

Represents a workflow column / stage:

typescript
export interface KanbanColumn {
  id: string;              // Unique column identifier
  title?: string;          // Human-readable header title
  wipLimit?: number;       // Maximum recommended card capacity
  items: KanbanItem[];     // Array of card items in this column
  allowAdd?: boolean;      // Renders "+ Add Task" button
  headerActions?: boolean; // Renders column action ellipsis menu
}

KanbanItem

Represents a task card:

typescript
export interface KanbanItem {
  id: string;               // Unique card identifier
  title?: string;           // Primary card title
  description?: string;     // Secondary card summary
  badge?: {                 // Priority or status badge
    text: string;
    variant?: 'default' | 'primary' | 'success' | 'warning' | 'danger';
  };
  assignee?: {              // Assigned team member
    name: string;
    avatarUrl?: string;
    initials?: string;
  };
  dueDate?: string;         // Target deadline date string
  isOverdue?: boolean;      // Overdue visual state flag
  subtasks?: {              // Subtask count progress
    completed: number;
    total: number;
  };
}

1. Framework-Agnostic Core Event Flow

When using the core DOM engine, pass callbacks to intercept lifecycle and drag actions:

typescript
import { createKanbanBoard } from '@nofinite/kanban';
import '@nofinite/nuicss/styles.css';

const board = createKanbanBoard(document.getElementById('board'), {
  columns: initialColumns,
  enforceWipLimit: true,
  onCardMove: (event: CardMoveEvent) => {
    console.log(`Card ${event.cardId} moved from ${event.sourceColumnId} (index ${event.sourceIndex}) to ${event.targetColumnId} (index ${event.targetIndex})`);
  },
  onColumnMove: (event: ColumnMoveEvent) => {
    console.log(`Column ${event.columnId} moved from index ${event.sourceIndex} to ${event.targetIndex}`);
  },
  onCardClick: (item, columnId) => {
    console.log('Opened task detail drawer:', item.id);
  }
});

2. React Adapter Integration

In React applications, bind standard React state to <Kanban />:

tsx
import React, { useState } from 'react';
import { Kanban, type KanbanColumnProps } from '@nofinite/kanban/react';
import '@nofinite/nuicss/styles.css';

export function SprintBoard() {
  const [columns, setColumns] = useState<KanbanColumnProps[]>(initialColumns);

  return (
    <Kanban
      columns={columns}
      onChange={setColumns}
      onCardMove={(event) => console.log('Card moved:', event)}
      onColumnMove={(event) => console.log('Column moved:', event)}
      enforceWipLimit={true}
    />
  );
}