);
})}
{(showDone || showArchive) && (
)}
{showArchive && (
)}
)}
);
}
```
## Installation
```bash
pnpm dlx @docyrus/cli add @docyrus/ui-kanban
```
**Dependencies:**
- [@dnd-kit/sortable](https://www.npmjs.com/package/@dnd-kit/sortable)
- [@dnd-kit/core](https://www.npmjs.com/package/@dnd-kit/core)
- [@dnd-kit/utilities](https://www.npmjs.com/package/@dnd-kit/utilities)
- [@radix-ui/react-slot](https://www.npmjs.com/package/@radix-ui/react-slot)
- [@types/react](https://www.npmjs.com/package/@types/react)
## Usage
```tsx
import {
Kanban,
KanbanBoard,
KanbanColumn,
KanbanColumnHandle,
KanbanItem,
KanbanItemHandle,
KanbanItemTitle,
KanbanOverlay,
KanbanFinalZone,
KanbanFinalColumn
} from '@docyrus/ui/components/kanban';
const [columns, setColumns] = useState({
todo: [{ id: '1', title: 'Task 1' }, { id: '2', title: 'Task 2' }],
done: [{ id: '3', title: 'Task 3' }]
});
{items.map((item) => (
))}
))}
```
### With Final Drop Zones
Use `finalColumns` on `Kanban` and `KanbanFinalZone` + `KanbanFinalColumn` to create drop targets that remove items from columns (e.g., archive or complete).
```tsx
```
### With Custom Overlay
The `KanbanOverlay` children can be a render function that receives the active item's value and variant.
```tsx
```
### Item Detail
Use `onItemClick` and `KanbanItemTitle` to open item details. `KanbanItemTitle` creates a clickable title zone that prevents drag-and-drop and triggers the callback instead.
```tsx
{items.map((item) => (
{item.description}
))}
))}
```
### Vertical Layout
Set `orientation="vertical"` for a top-to-bottom column layout.
```tsx
```
## Components
| Component | Description |
|-----------|-------------|
| `Kanban` | Root provider. Wraps `DndContext` with collision detection, keyboard navigation, and screen reader announcements. |
| `KanbanBoard` | Container for columns. Renders a `SortableContext` for column reordering. |
| `KanbanColumn` | A sortable column container. Renders a `SortableContext` for its items. |
| `KanbanColumnHandle` | Drag handle for reordering columns. Must be inside `KanbanColumn`. |
| `KanbanItem` | A sortable item within a column. Supports cross-column drag. |
| `KanbanItemHandle` | Drag handle for items. Must be inside `KanbanItem`. |
| `KanbanItemTitle` | Clickable title zone inside `KanbanItem`. Prevents drag-and-drop and fires `onItemClick`. |
| `KanbanOverlay` | Portal-rendered drag overlay preview. Accepts a render function for custom previews. |
| `KanbanFinalZone` | Container for final drop columns. Only visible during item drag. |
| `KanbanFinalColumn` | A droppable target inside `KanbanFinalZone` that triggers `onFinalDrop`. |
## API Reference
### Kanban
The root component. Manages drag state, collision detection, and value changes.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `Record` | — | Column data. Keys are column IDs, values are item arrays. |
| `onValueChange` | `(columns: Record) => void` | — | Called when items are moved between or within columns. |
| `getItemValue` | `(item: T) => UniqueIdentifier` | — | Extracts a unique ID from each item. Required when `T` is an object. |
| `onMove` | `(event: DragEndEvent & { activeIndex: number; overIndex: number }) => void` | — | Called on reorder instead of `onValueChange` when provided. Useful for server-side persistence. |
| `onFinalDrop` | `(item: T, finalColumnId: UniqueIdentifier) => void` | — | Called when an item is dropped onto a `KanbanFinalColumn`. |
| `onItemClick` | `(value: UniqueIdentifier) => void` | — | Called when a `KanbanItemTitle` is clicked. Receives the item's value. |
| `finalColumns` | `UniqueIdentifier[]` | — | IDs of final drop columns (must match `KanbanFinalColumn` values). |
| `strategy` | `SortableContextProps['strategy']` | `verticalListSortingStrategy` | Sorting strategy for items within columns. |
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Board layout direction. |
| `flatCursor` | `boolean` | `false` | Use `cursor-default` instead of `cursor-grab` for all drag handles. |
| `modifiers` | `DndContextProps['modifiers']` | — | dnd-kit modifiers for constraining drag movement. |
| `accessibility` | `DndContextProps['accessibility']` | — | Custom accessibility announcements (merged with built-in announcements). |
### KanbanBoard
Container for columns. Must be inside `Kanban`.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `asChild` | `boolean` | `false` | Render as child element using `Slot`. |
| `className` | `string` | — | Additional CSS classes. |
### KanbanColumn
A sortable column. Must be inside `KanbanBoard` or `KanbanOverlay`.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `UniqueIdentifier` | — | Unique column identifier. Must match a key in `Kanban`'s `value`. |
| `asChild` | `boolean` | `false` | Render as child element using `Slot`. |
| `asHandle` | `boolean` | `false` | Make the entire column a drag handle. |
| `disabled` | `boolean` | `false` | Disable column dragging. |
| `className` | `string` | — | Additional CSS classes. |
### KanbanColumnHandle
Drag handle for columns. Must be inside `KanbanColumn`.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `asChild` | `boolean` | `false` | Render as child element using `Slot`. |
| `disabled` | `boolean` | — | Override column's disabled state. |
| `className` | `string` | — | Additional CSS classes. |
### KanbanItem
A sortable item. Must be inside `KanbanColumn` (within `KanbanBoard` or `KanbanOverlay`).
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `UniqueIdentifier` | — | Unique item identifier. Must match the value returned by `getItemValue`. |
| `asChild` | `boolean` | `false` | Render as child element using `Slot`. |
| `asHandle` | `boolean` | `false` | Make the entire item a drag handle. |
| `disabled` | `boolean` | `false` | Disable item dragging. |
| `className` | `string` | — | Additional CSS classes. |
### KanbanItemHandle
Drag handle for items. Must be inside `KanbanItem`.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `asChild` | `boolean` | `false` | Render as child element using `Slot`. |
| `disabled` | `boolean` | — | Override item's disabled state. |
| `className` | `string` | — | Additional CSS classes. |
### KanbanItemTitle
Clickable title zone inside `KanbanItem`. Intercepts pointer events to prevent drag-and-drop activation, and fires the root `onItemClick` callback on click. Renders a `