Skip to content

Pro Component — This component requires an Aura UI Pro license.

Overview

The Kanban component provides a drag-and-drop board layout with columns and cards, commonly used for project management, task tracking, and workflow visualization. Cards can be dragged between columns, and the component dispatches events so you can persist changes via Livewire.

Basic Usage

To Do
In Progress
Done
<x-aura::kanban>
    <x-aura::kanban.column title="To Do" color="gray">
        <x-aura::kanban.card title="Design homepage" description="Create wireframes and mockups" />
        <x-aura::kanban.card title="Write API docs" />
    </x-aura::kanban.column>

    <x-aura::kanban.column title="In Progress" color="blue">
        <x-aura::kanban.card title="Build auth flow" description="Login, register, password reset" />
    </x-aura::kanban.column>

    <x-aura::kanban.column title="Done" color="green">
        <x-aura::kanban.card title="Database schema" description="All migrations complete" />
    </x-aura::kanban.column>
</x-aura::kanban>

Props

Kanban

The root component has no configurable props. It manages drag-and-drop state internally via Alpine.js.

Kanban Column

Prop Type Default Description
title string '' Column heading text.
color string 'gray' Column accent color: gray, blue, green, yellow, red, purple, pink.

Kanban Card

Prop Type Default Description
title string '' Card heading text.
description string|null null Optional description text below the title.

Examples

Project Management Board

Backlog
To Do
In Progress
Review
Done
<x-aura::kanban>
    <x-aura::kanban.column title="Backlog" color="gray">
        <x-aura::kanban.card
            title="User avatars"
            description="Allow users to upload profile pictures"
        />
        <x-aura::kanban.card
            title="Email templates"
            description="Design transactional email layouts"
        />
    </x-aura::kanban.column>

    <x-aura::kanban.column title="To Do" color="yellow">
        <x-aura::kanban.card
            title="Payment integration"
            description="Stripe checkout and webhooks"
        />
    </x-aura::kanban.column>

    <x-aura::kanban.column title="In Progress" color="blue">
        <x-aura::kanban.card
            title="Dashboard redesign"
            description="New layout with analytics widgets"
        />
        <x-aura::kanban.card
            title="API rate limiting"
            description="Implement throttle middleware"
        />
    </x-aura::kanban.column>

    <x-aura::kanban.column title="Review" color="purple">
        <x-aura::kanban.card
            title="Search feature"
            description="Full-text search with Meilisearch"
        />
    </x-aura::kanban.column>

    <x-aura::kanban.column title="Done" color="green">
        <x-aura::kanban.card title="Auth system" description="Login, register, 2FA" />
        <x-aura::kanban.card title="Database migrations" />
    </x-aura::kanban.column>
</x-aura::kanban>

Livewire Dynamic Board

<!-- Blade view -->
<x-aura::kanban
    x-on:kanban-card-moved="$wire.moveTask($event.detail.cardId, $event.detail.toColumn, $event.detail.position)"
>
    @foreach($columns as $column)
        <x-aura::kanban.column :title="$column['title']" :color="$column['color']">
            @foreach($column['tasks'] as $task)
                <x-aura::kanban.card
                    :title="$task['title']"
                    :description="$task['description']"
                    x-data="{ id: {{ $task['id'] }} }"
                />
            @endforeach
        </x-aura::kanban.column>
    @endforeach
</x-aura::kanban>
// Livewire component
class TaskBoard extends Component
{
    public array $columns = [];

    public function mount(): void
    {
        $this->loadBoard();
    }

    public function moveTask(int $taskId, string $toColumn, int $position): void
    {
        $task = Task::findOrFail($taskId);
        $task->update([
            'status' => $toColumn,
            'sort_order' => $position,
        ]);

        $this->loadBoard();
    }

    private function loadBoard(): void
    {
        $statuses = [
            ['key' => 'todo', 'title' => 'To Do', 'color' => 'yellow'],
            ['key' => 'in_progress', 'title' => 'In Progress', 'color' => 'blue'],
            ['key' => 'review', 'title' => 'Review', 'color' => 'purple'],
            ['key' => 'done', 'title' => 'Done', 'color' => 'green'],
        ];

        $this->columns = collect($statuses)->map(fn ($s) => [
            'title' => $s['title'],
            'color' => $s['color'],
            'tasks' => Task::where('status', $s['key'])
                ->orderBy('sort_order')
                ->get(['id', 'title', 'description'])
                ->toArray(),
        ])->toArray();
    }
}

Minimal Two-Column Board

Active
Completed
<x-aura::kanban>
    <x-aura::kanban.column title="Active" color="blue">
        <x-aura::kanban.card title="Current sprint tasks" />
    </x-aura::kanban.column>

    <x-aura::kanban.column title="Completed" color="green">
        <x-aura::kanban.card title="Finished tasks" />
    </x-aura::kanban.column>
</x-aura::kanban>

Slots

Slot Component Description
default kanban Contains kanban.column children.
default kanban.column Contains kanban.card children.
default kanban.card Optional custom content to render inside the card body.

Card with Custom Content

Design Due: Feb 20
<x-aura::kanban.card title="Design system">
    <div class="mt-2 flex items-center gap-2">
        <x-aura::badge variant="info" size="sm">Design</x-aura::badge>
        <span class="text-xs text-gray-500">Due: Feb 20</span>
    </div>
</x-aura::kanban.card>

Accessibility

  • Cards use role="listitem" within columns that use role="list".
  • Drag handles include aria-label="Drag to reorder" and are focusable.
  • aria-grabbed indicates the drag state of a card.
  • aria-dropeffect="move" is set on columns when a card is being dragged.
  • Keyboard drag-and-drop is supported: Space to grab/release, Arrow keys to move.
  • Screen readers announce when a card is picked up, moved to a new column, or dropped.
  • Column headers use role="heading" with appropriate level for semantic structure.