# Kanban

> Board of columns with draggable cards and WIP limits.

Source: https://ui.jcsoftdev.com/docs/components/kanban

Board of columns with draggable cards and WIP limits. Pointer: drag a card (touch: use the
grip). Keyboard: Space or Enter picks a card up, arrows move it, Space or Enter drops it,
Escape cancels. Moves are announced in a live region.

## Import

```ts
import { Kanban } from "@jcsoftdev/ui/containers";
```

Single-component entry points tree-shake to just this component: `@jcsoftdev/ui/containers/kanban`.

## Usage

```tsx
<Kanban
  defaultColumns={columns}
  enforceLimit={false}
  emptyLabel="Sin citas"
/>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `columns` | `KanbanColumnData[]` |  | Controlled board. Pair with `onColumnsChange`. |
| `defaultColumns` | `KanbanColumnData[]` | `[]` |  |
| `onColumnsChange` | `((columns: KanbanColumnData[], move: KanbanMove) => void)` |  | Called after a drop (pointer release or keyboard drop) with the new board and the move. |
| `enforceLimit` | `boolean` | `false` | Refuse drops into another column that already reached its WIP limit. |
| `renderCard` | `((card: KanbanCardData) => ReactNode)` |  | Replaces the default card body. |
| `emptyLabel` | `string` | `"Sin tarjetas"` |  |
| `aria-label` | `string` |  |  |
| `className` | `string` |  |  |

`*` marks a required prop.

## Storybook stories

- [Default](/storybook/?path=/story/containers-kanban--default)
- [Enforced Limit](/storybook/?path=/story/containers-kanban--enforced-limit)
- [Narrow](/storybook/?path=/story/containers-kanban--narrow)
- [Brutal Preset](/storybook/?path=/story/containers-kanban--brutal-preset)
- [Glass Compact](/storybook/?path=/story/containers-kanban--glass-compact)

## Source

`packages/ui/src/containers/kanban/kanban.tsx`
