---
title: Kanban
description: Horizontal scrollable board of status columns
visibility: guest
draft: false
---

# Kanban

A board-and-column layout for task management, pipelines, and workflow visualization. Supports horizontal scrolling, WIP limits, intent-based column accents, and drag-and-drop integration.

## Basic Usage

:::preview{title="Simple kanban board" wide}
<x-wirekit::kanban>
    <x-wirekit::kanban-column label="To Do" :count="2">
        <x-wirekit::card><x-wirekit::card.body>Design homepage</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Write copy</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
    <x-wirekit::kanban-column label="In Progress" :count="1" intent="primary">
        <x-wirekit::card><x-wirekit::card.body>Build API</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
    <x-wirekit::kanban-column label="Done" :count="1" intent="success">
        <x-wirekit::card><x-wirekit::card.body>Setup CI/CD</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
</x-wirekit::kanban>
:::

## Intent-Based Column Accents

Color the top border to visually distinguish column stages:

:::preview{title="Column intent variants" wide}
<x-wirekit::kanban>
    <x-wirekit::kanban-column label="Backlog" :count="4">
        <x-wirekit::card><x-wirekit::card.body>Research competitors</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Draft project brief</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Schedule kickoff call</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Prepare mood board</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
    <x-wirekit::kanban-column label="Active" :count="2" intent="info">
        <x-wirekit::card><x-wirekit::card.body>Wireframe dashboard</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>API endpoint spec</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
    <x-wirekit::kanban-column label="Review" :count="1" intent="warning">
        <x-wirekit::card><x-wirekit::card.body>Auth flow PR</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
    <x-wirekit::kanban-column label="Complete" :count="3" intent="success">
        <x-wirekit::card><x-wirekit::card.body>Repo bootstrap</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>CI pipeline setup</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Style-guide v1</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
</x-wirekit::kanban>
:::

## WIP Limits

Set a `limit` per column. The count badge turns danger when the column exceeds capacity:

:::preview{title="WIP limit enforcement" wide}
<x-wirekit::kanban>
    <x-wirekit::kanban-column label="In Progress" :count="3" :limit="5">
        <x-wirekit::card><x-wirekit::card.body>Refactor billing module</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Localize checkout flow</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Performance audit</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
    <x-wirekit::kanban-column label="Review" :count="6" :limit="5">
        <x-wirekit::card><x-wirekit::card.body>Onboarding redesign PR</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Email-template refresh</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Search index migration</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Webhook retry logic</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Audit-log viewer</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Account-deletion endpoint</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
</x-wirekit::kanban>
:::

## Column Footer

Add actions (like "Add item") below the cards:

:::preview{title="Column with footer" wide}
<x-wirekit::kanban>
    <x-wirekit::kanban-column label="To Do" :count="1">
        <x-wirekit::card><x-wirekit::card.body>Existing task</x-wirekit::card.body></x-wirekit::card>
        <x-slot:footer>
            <x-wirekit::button size="sm" intent="neutral" surface="ghost" class="w-full">+ Add task</x-wirekit::button>
        </x-slot:footer>
    </x-wirekit::kanban-column>
</x-wirekit::kanban>
:::

## Custom Column Header

Replace the default header with your own content:

:::preview{title="Custom header slot" wide}
<x-wirekit::kanban>
    <x-wirekit::kanban-column label="Custom">
        <x-slot:header>
            <x-wirekit::row gap="sm" class="px-4 py-2">
                <x-wirekit::badge intent="primary">Sprint 4</x-wirekit::badge>
                <x-wirekit::text size="sm">3 items</x-wirekit::text>
            </x-wirekit::row>
        </x-slot:header>
        <x-wirekit::card><x-wirekit::card.body>Plan retro agenda</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Update release notes</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Demo prep</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
</x-wirekit::kanban>
:::

## Vertical Orientation

Stack columns vertically instead of horizontally:

:::preview{title="Vertical kanban" wide}
<x-wirekit::kanban orientation="vertical">
    <x-wirekit::kanban-column label="Stage 1" :count="2">
        <x-wirekit::card><x-wirekit::card.body>Discovery interviews</x-wirekit::card.body></x-wirekit::card>
        <x-wirekit::card><x-wirekit::card.body>Define success metrics</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
    <x-wirekit::kanban-column label="Stage 2" :count="1" intent="success">
        <x-wirekit::card><x-wirekit::card.body>Approved roadmap</x-wirekit::card.body></x-wirekit::card>
    </x-wirekit::kanban-column>
</x-wirekit::kanban>
:::

## Kanban Board Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `orientation` | `string` | `'horizontal'` | Layout direction: `horizontal` or `vertical` |
| `sortable` | `bool` | `false` | Enable drag-and-drop data attributes |

## Kanban Column Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `label` | `string` | `null` | Column heading text |
| `count` | `int` | `null` | Number of items (shown as badge) |
| `intent` | `string` | `'neutral'` | Top border accent: `neutral`, `primary`, `success`, `warning`, `danger`, `info` |
| `limit` | `int` | `null` | WIP limit (badge turns danger when exceeded) |
| `sortable` | `bool` | `false` | Enable drag-and-drop data attributes |

## Column Slots

| Slot | Description |
|------|-------------|
| default | Card items inside the column |
| `header` | Replace the default column header |
| `footer` | Action area below the cards |

## Accessibility

- Board: `role="list"` for the column collection
- Column: `<section role="listitem">` with `aria-labelledby` linking to the column label
- Sortable: `data-sortable`, `data-sortable-column`, `data-sortable-items` attributes for DnD library integration (SortableJS, etc.)

## Keyboard Interaction

| Key | Action |
|-----|--------|
| `Tab` | Move focus through draggable cards |

::: info
The default Kanban primitive is presentational — drag-and-drop wiring (and any keyboard reordering) is supplied by you. See [Customization](/customization) for integration recipes.
:::

## Pitfalls

- **Don't render a kanban without a drag-drop integration.** The primitive is presentational — drag-and-drop is intentionally not bundled (libraries clash). See [Customization](/customization).

## Design Tokens

| Token | Used for |
| --- | --- |
| `--font-wk-sans` | Kanban font family |
| `--font-wk-heading-weight` | Column title weight |
| `--text-wk-sm` | Column title + count badge font size |
| `--color-wk-text` | Column title |
| `--color-wk-bg-muted` | Column body background |
| `--color-wk-border` / `--color-wk-border-subtle` | Column border + separator |
| `--color-wk-accent` / `--color-wk-success` / `--color-wk-warning` / `--color-wk-danger` | Top-border accent per `intent` |
| `--color-wk-ring` / `--color-wk-ring-offset` | Focus ring |
| `--ring-wk-width` / `--ring-wk-offset` | Focus ring geometry |
| `--border-wk-width` | Border width |
| `--radius-wk-lg` | Column border radius |
