Dice UI

Kanban

A drag and drop kanban board component for organizing items into columns.

DocsAPI

Installation

pnpm dlx shadcn@latest add @diceui/kanban

Layout

Import the parts, and compose them together.

import {
  Kanban,
  KanbanBoard,
  KanbanColumn,
  KanbanColumnHandle,
  KanbanItem,
  KanbanItemHandle,
  KanbanOverlay,
} from "@/components/ui/kanban";
 
return (
  <Kanban>
    <KanbanBoard>
      <KanbanColumn>
        <KanbanColumnHandle />
        <KanbanItem>
          <KanbanItemHandle />
        </KanbanItem>
      </KanbanColumn>
    </KanbanBoard>
    <KanbanOverlay />
  </Kanban>
)

Usage

With Primitive Values

When using primitive arrays (strings, numbers), the getItemValue prop is optional. The component will automatically use the items themselves as unique identifiers.

const [columns, setColumns] = React.useState({
  todo: ["Task 1", "Task 2"],
  done: ["Task 3"],
});
 
<Kanban.Kanban value={columns} onValueChange={setColumns}>
  <Kanban.Board>
    {Object.entries(columns).map(([columnId, items]) => (
      <Kanban.Column key={columnId} value={columnId}>
        {items.map((item) => (
          <Kanban.Item key={item} value={item}>
            {item}
          </Kanban.Item>
        ))}
      </Kanban.Column>
    ))}
  </Kanban.Board>
</Kanban.Kanban>

With Object Arrays

When using object arrays, the getItemValue prop is required to extract unique identifiers from each item.

const [columns, setColumns] = React.useState({
  todo: [
    { id: 1, title: "Task 1" },
    { id: 2, title: "Task 2" },
  ],
  done: [
    { id: 3, title: "Task 3" },
  ],
});
 
<Kanban.Kanban
  value={columns}
  onValueChange={setColumns}
  getItemValue={(item) => item.id}
>
  <Kanban.Board>
    {Object.entries(columns).map(([columnId, items]) => (
      <Kanban.Column key={columnId} value={columnId}>
        {items.map((item) => (
          <Kanban.Item key={item.id} value={item.id}>
            {item.title}
          </Kanban.Item>
        ))}
      </Kanban.Column>
    ))}
  </Kanban.Board>
</Kanban.Kanban>

Examples

With Dynamic Overlay

Display a dynamic overlay when an item or column is being dragged.

API Reference

Kanban

The main container component for kanban board functionality.

Prop

Type

KanbanBoard

Container for kanban columns.

Prop

Type

Column

Individual kanban column component.

Prop

Type

Data AttributeValue
[data-disabled]Present when the column is disabled.
[data-dragging]Present when the column is being dragged.

ColumnHandle

A button component that acts as a drag handle for kanban columns.

Prop

Type

Data AttributeValue
[data-disabled]Present when the column is disabled.
[data-dragging]Present when the parent column is being dragged.

KanbanItem

Individual kanban item component.

Prop

Type

Data AttributeValue
[data-disabled]Present when the item is disabled.
[data-dragging]Present when the item is being dragged.

KanbanItemHandle

A button component that acts as a drag handle for kanban items.

Prop

Type

Data AttributeValue
[data-disabled]Present when the item is disabled.
[data-dragging]Present when the parent item is being dragged.

Overlay

The overlay component that appears when an item or column is being dragged.

Prop

Type

Accessibility

Keyboard Interactions

KeyDescription
EnterSpacePicks up the kanban item or column for reordering when released, and drops it in its new position when pressed again.
ArrowUpMoves the kanban item up in vertical orientation.
ArrowDownMoves the kanban item down in vertical orientation.
ArrowLeftMoves the kanban item left in horizontal orientation.
ArrowRightMoves the kanban item right in horizontal orientation.
EscCancels the drag operation and returns the item or column to its original position.

On this page