Skip to content

Kanban item

A draggable item inside a FluxKanbanColumn. The item-id uniquely identifies the item and the column-id must match the parent column. The kanban board uses both to compute drop targets and to populate the move event.

The component itself is intentionally unstyled. It only adds the interaction layer (drag handle, focus ring, drop indicator). The visual surface (padding, background, border, shadows) is up to you. Render any markup inside the default slot; the examples below all wrap their content in a <div class="card"> with a <style scoped> block.

Keyboard support

An item is focusable. Press Space or Enter to pick it up, use / to reposition within the column, / to move to a sibling column, Enter/Space to drop and Escape to cancel.

To do
Design system review

Props

column-id: string | number
The column this item currently belongs to. Must match the parent FluxKanbanColumn's column-id.

disabled?: boolean
Disables drag-and-drop for this item. The item stays visible but cannot be picked up or focused.
Default: false

item-id: string | number
Unique identifier for this item. Included in move events.

Slots

default
The content of the item. The component is unstyled. Render whatever markup (and styling) you want here.

Examples

Basic

A minimal item with just a title.

To do
Design system review
Write unit tests
Update documentation

<template>
    <FluxKanban style="max-width: 100%">
        <FluxKanbanColumn
            column-id="todo"
            label="To do">
            <FluxKanbanItem
                item-id="1"
                column-id="todo">
                <div class="card">
                    Design system review
                </div>
            </FluxKanbanItem>

            <FluxKanbanItem
                item-id="2"
                column-id="todo">
                <div class="card">
                    Write unit tests
                </div>
            </FluxKanbanItem>

            <FluxKanbanItem
                item-id="3"
                column-id="todo">
                <div class="card">
                    Update documentation
                </div>
            </FluxKanbanItem>
        </FluxKanbanColumn>
    </FluxKanban>
</template>

<script
    lang="ts"
    setup>
    import { FluxKanban, FluxKanbanItem, FluxKanbanColumn } from '@flux-ui/components';
</script>

<style scoped>
    .card {
        padding: 12px;
        background: var(--gray-25);
        border: 1px solid var(--gray-200);
        border-radius: var(--radius);
        transition: box-shadow 180ms var(--swift-out);
    }

    .card:hover {
        box-shadow: 0 1px 4px rgb(0 0 0 / .08);
    }
</style>

Rich content

An item with a title, description and a priority badge.

In progress
Refactor auth module
High

Clean up token handling and session storage.

<template>
    <FluxKanban style="max-width: 100%">
        <FluxKanbanColumn
            column-id="in-progress"
            label="In progress">
            <FluxKanbanItem
                item-id="1"
                column-id="in-progress">
                <div class="card">
                    <div class="card-header">
                        <span class="card-title">Refactor auth module</span>
                        <FluxBadge
                            color="danger"
                            label="High"
                            type="none"/>
                    </div>

                    <p class="card-description">
                        Clean up token handling and session storage.
                    </p>

                    <div class="card-footer">
                        <span class="card-assignee">Alice</span>
                    </div>
                </div>
            </FluxKanbanItem>
        </FluxKanbanColumn>
    </FluxKanban>
</template>

<script
    lang="ts"
    setup>
    import { FluxBadge, FluxKanban, FluxKanbanItem, FluxKanbanColumn } from '@flux-ui/components';
</script>

<style scoped>
    .card {
        padding: 12px;
        background: var(--gray-25);
        border: 1px solid var(--gray-200);
        border-radius: var(--radius);
        transition: box-shadow 180ms var(--swift-out);
    }

    .card:hover {
        box-shadow: 0 1px 4px rgb(0 0 0 / .08);
    }

    .card-header {
        display: flex;
        align-items: flex-start;
        gap: 8px;
        justify-content: space-between;
    }

    .card-title {
        font-size: .875rem;
        font-weight: 500;
        color: var(--foreground);
        line-height: 1.4;
    }

    .card-description {
        margin: 6px 0 0;
        font-size: .8125rem;
        color: var(--gray-500);
        line-height: 1.5;
    }

    .card-footer {
        display: flex;
        align-items: center;
        margin-top: 10px;
        padding-top: 10px;
        border-top: 1px solid var(--gray-100);
    }

    .card-assignee {
        font-size: .8125rem;
        color: var(--gray-500);
    }
</style>

Used components