Preview Updated 2026-05-10

Kanban

Multi-column card board using native HTML5 drag-and-drop to move cards across columns; supports WIP limits and column accent colors.

Basic usage

CfKanban accepts a KanbanColumn[], where each column has id / title / cards, and each card may have title / description / tag / meta. Drag a card onto another card or empty column to move it; on drop the component updates modelValue and fires cardMove.

待办2
设计登录页
design
梳理 API 字段
backend
进行中1 / 3
埋点 SDK 接入
frontend@小明
已完成1
更新 README
昨天
<script setup lang="ts">
import { ref } from 'vue';
import { CfKanban, type KanbanColumn } from '@chufix-design/vue';

const board = ref<KanbanColumn[]>([
{
  id: 'todo',
  title: 'To do',
  cards: [
    { id: 'c1', title: 'Design login page', tag: 'design' },
    { id: 'c2', title: 'Outline API fields', tag: 'backend' },
  ],
},
{
  id: 'doing',
  title: 'In progress',
  limit: 3,
  cards: [{ id: 'c3', title: 'Integrate analytics SDK', tag: 'frontend', meta: '@alex' }],
},
{
  id: 'done',
  title: 'Done',
  accent: 'oklch(70% 0.16 145)',
  cards: [{ id: 'c4', title: 'Update README', meta: 'Yesterday' }],
},
]);
</script>

<template>
<CfKanban v-model="board" />
</template>
import { useState } from 'react';
import { CfKanban, type KanbanColumn } from '@chufix-design/react';

export default function Demo() {
const [board, setBoard] = useState<KanbanColumn[]>([
  {
    id: 'todo',
    title: 'To do',
    cards: [
      { id: 'c1', title: 'Design login page', tag: 'design' },
      { id: 'c2', title: 'Outline API fields', tag: 'backend' },
    ],
  },
  { id: 'doing', title: 'In progress', limit: 3, cards: [
    { id: 'c3', title: 'Integrate analytics SDK', tag: 'frontend', meta: '@alex' },
  ] },
  { id: 'done', title: 'Done', accent: 'oklch(70% 0.16 145)', cards: [
    { id: 'c4', title: 'Update README', meta: 'Yesterday' },
  ] },
]);
return <CfKanban value={board} onChange={setBoard} />;
}

Column limit and accent color

column.limit shows as used / limit in the header (the number is a hint only — drops are not blocked). column.accent tints the header title — useful for visualizing semantics like “priority / status / owner”.

Backlog3
设计 Brand 系统
design
梳理 SLA 表
docs
调研监控方案
进行中2 / 2
新版仪表盘
frontend@小明
统一鉴权 SDK
backend@小红
待评审1
埋点白名单
data
已完成2
部署稳定性周报
昨天
修复时区 bug
bugfix前天
const board = ref<KanbanColumn[]>([
{
  id: 'wip', title: 'In progress', limit: 2,
  accent: 'oklch(70% 0.16 60)',
  cards: [/* ... */],
},
// ...
]);

<CfKanban v-model="board" />
const [board, setBoard] = useState<KanbanColumn[]>([
{
  id: 'wip', title: 'In progress', limit: 2,
  accent: 'oklch(70% 0.16 60)',
  cards: [/* ... */],
},
// ...
]);

<CfKanban value={board} onChange={setBoard} />

Disable drag

draggable={false} turns off all interaction — a read-only board view. Cards still render from props; only the cursor and dragstart listeners are removed.

待办2
设计登录页
design
梳理 API 字段
backend
进行中1
埋点 SDK 接入
frontend@小明
已完成1
更新 README
昨天
<CfKanban v-model="board" :draggable="false" />
<CfKanban value={board} onChange={setBoard} draggable={false} />

API

PropTypeDefaultDescription
modelValue (Vue) / value (React)KanbanColumn[][]Full board state
defaultValueKanbanColumn[][]Uncontrolled initial value
draggablebooleantrueEnable HTML5 drag-and-drop
borderedbooleantrueBorder
size'sm' | 'md' | 'lg''md'Font size

Events:

  • onChange(cols) / update:modelValue — any change to the board
  • onCardMove({ cardId, from, to, toIndex }) / card-move — fires after a card moves; payload contains source column, target column, and destination index

Type exports:

interface KanbanCard {
  id: string;
  title: string;
  description?: string;
  tag?: string;
  meta?: string;
}
interface KanbanColumn {
  id: string;
  title: string;
  cards: KanbanCard[];
  limit?: number;
  accent?: string;
}

反馈与讨论

Kanban · Discussion

0
0 / 600
一键发送
正在加载评论...