Docs Platform

Kanban

A board of columns and cards. The machine tracks whether a card is idle, grabbed or being dragged, and which column it belongs to. Titles, priorities and assignees stay yours. Native HTML5 drag still works as it always did, and keyboard grab/move/drop is added on top rather than replacing it. Selection is the generic opaque-ID machine, defaulting to none.

Live machine

The shipped kanbanMachine. Grab a card, then pick a column — placements only commit on the drop, and cancel restores them.

kanban · live via createService

States · walked from the machine

active

Transitions from here · click to send

Context

{
  "mode": "uncontrolled",
  "placements": [
    {
      "cardId": "checkout-flow",
      "columnId": "todo"
    },
    {
      "cardId": "search-index",
      "columnId": "todo"
    },
    {
      "cardId": "billing-retry",
      "columnId": "doing"
    },
    {
      "cardId": "dark-mode",
      "columnId": "done"
    }
  ],
  "dragStatus": "idle",
  "sourceCardId": null,
  "sourceColumnId": null,
  "targetColumnId": null,
  "selection": {
    "value": "ready",
    "context": {
      "mode": "uncontrolled",
      "selectedIds": [],
      "anchorId": null
    }
  }
}

Log · newest first

No events yet — use the component above or send a transition.

Explore the layers

Machine (@grassroot/ui-machines/kanban): placements plus nested selectionMachine. Headless: five adapters plus mountKanban. Styled: five @grassroot/ui-* Kanban rewrites on those adapters, still emitting the live onMove edge. Package exports and browser-server routes are orchestrator-owned.

Behaviour contract

See packages/ui-headless/core/src/kanban/kanban.spec.md. Oracle: frozen reduceKanbanDrag / moveCard / cardsByColumn. Unknown IDs and same-column drops are same-reference no-ops. disableDrag blocks pointer and keyboard.

Anatomy

root, keyed column / header / card, optional live. Columns are role="list"; cards are role="listitem".

Selection reuse

Nested selectionMachine from packages/ui-machines/src/selection. Default mode none matches live Kanban. Opaque string IDs are card IDs. Space stays grab/drop and is not forwarded to selection.

Keyboard and pointer

Pointer: native dragstart / dragover / dragleave / drop / dragend. Keyboard (versioned): Space grab/drop, Escape cancel, Left/Right/Home/End retarget column. Announcement keys: kanban.grabbed, kanban.column, kanban.dropped, kanban.cancelled.