KanbanBoard

App

Trello / Linear-style kanban board. M1 ships HTML5-native drag and drop between columns with an inline drop-position indicator (thin line between cards) and full optimistic-UI rewind via window.KuiKanban.get(id).setMover() — throw / reject from the mover to revert. Future milestones: column reorder + collapse + WIP limits (M2), swimlanes + filters + search (M3), inline edit + bulk select + card detail panel (M4), keyboard nav + ARIA announcements (M5), virtualization + auto-archive + dependencies (M6). Pixel-identical React sibling at modules/app/KanbanBoard/index.tsx.

Three columns (basic)

Preview

To Do

3
  • Audit dark-mode tokens

    medium design
  • Wire i18n for /account

    low i18n
  • Fix flaky e2e on Firefox

    urgent bug

In Progress

2
  • Refactor Quill toolbar

    medium JD
  • Document KanbanBoard API

    JS AL

Done

1
  • Ship release notes

    high docs
Code
<%- include('modules/app/KanbanBoard', {
  id: 'engineering-board',
  ariaLabel: 'Engineering board',
  columns: [
    { id: 'todo',  title: 'To Do' },
    { id: 'doing', title: 'In Progress' },
    { id: 'done',  title: 'Done' }
  ],
  cards: [
    { id: 'c1', columnId: 'todo',  title: 'Audit dark-mode tokens', priority: 'medium' },
    { id: 'c2', columnId: 'doing', title: 'Refactor Quill toolbar' }
  ]
}) %>

<script>
  // Persist + revert hook (mover may throw to roll back the optimistic move).
  window.KuiKanban.get('engineering-board').setMover(async function (card, from, to, index) {
    var r = await fetch('/api/cards/' + card.id, {
      method: 'PATCH', body: JSON.stringify({ columnId: to, index })
    });
    if (!r.ok) throw new Error(r.statusText);
  });
</script>

canMove validation

Preview

To Do

3
  • Audit dark-mode tokens

    medium design
  • Wire i18n for /account

    low i18n
  • Fix flaky e2e on Firefox

    urgent bug

In Progress

2
  • Refactor Quill toolbar

    medium JD
  • Document KanbanBoard API

    JS AL

Done

1
  • Ship release notes

    high docs
Code
<%- include('modules/app/KanbanBoard', { id: 'board', columns, cards }) %>
<script>
  window.KuiKanban.get('board')._canMove = function (card, from, to) {
    return from !== 'done' || to === 'done';
  };
</script>

Async mover with rollback

Preview

To Do

3
  • Audit dark-mode tokens

    medium design
  • Wire i18n for /account

    low i18n
  • Fix flaky e2e on Firefox

    urgent bug

In Progress

2
  • Refactor Quill toolbar

    medium JD
  • Document KanbanBoard API

    JS AL

Done

1
  • Ship release notes

    high docs
Code
<%- include('modules/app/KanbanBoard', { id: 'board', columns, cards }) %>
<script>
  window.KuiKanban.get('board').setMover(async function (card, from, to, index) {
    var r = await fetch('/api/move', {
      method: 'POST',
      body: JSON.stringify({ id: card.id, to: to, index: index })
    });
    if (!r.ok) throw new Error(r.statusText); // -> optimistic move rolls back
  });
</script>
Source modules/app/KanbanBoard/KanbanBoard.ejs