unnamed-ui
气泡/容器

Task List

Task management component with editable mode, checkboxes, and feedback options

学习计划待确认
  • 学习 React 基础
  • 掌握 TypeScript
  • 构建第一个项目
"use client";

import { useState } from "react";
import {
  TaskList,
  type TodoItem,
} from "@/components/composed/task-list/task-list";

const initialTasks: TodoItem[] = [
  { id: "1", content: "学习 React 基础", order: 1 },
  { id: "2", content: "掌握 TypeScript", order: 2 },
  { id: "3", content: "构建第一个项目", order: 3 },
];

export function TaskListDemo() {
  const [tasks, setTasks] = useState<TodoItem[]>(initialTasks);

  return (
    <TaskList
      dataSource={tasks}
      title="学习计划"
      status="pending"
      onItemsChange={setTasks}
      onConfirmExecute={() => {
        console.log("确认执行", tasks);
      }}
    />
  );
}

Task List 组件提供了完整的任务管理功能,支持任务的创建、编辑、完成状态切换和反馈,适用于待办事项、任务清单、工作流管理等场景。

概述

  • 双模式切换:支持只读模式和编辑模式,灵活适应不同场景
  • 任务操作:完成/未完成切换、添加新任务、编辑任务、删除任务
  • 反馈系统:每个任务支持点赞、点踩等反馈操作
  • 实时保存:编辑后自动保存,无需手动确认
  • 响应式设计:自适应不同屏幕尺寸
  • 类型安全:完整的 TypeScript 类型定义

快速开始

import { TaskList } from "@/registry/wuhan/composed/task-list";

const tasks = [
  { id: "1", text: "完成项目文档", completed: false },
  { id: "2", text: "代码审查", completed: true },
];

export function Example() {
  return (
    <TaskList
      tasks={tasks}
      onTasksChange={(newTasks) => console.log(newTasks)}
    />
  );
}

特性

  • 任务管理:创建、编辑、删除、完成状态切换
  • 编辑模式:一键切换到编辑模式,修改任务内容
  • 反馈功能:支持点赞、点踩等用户反馈
  • 键盘操作:支持 Enter 保存、Escape 取消等快捷键
  • 自动聚焦:新建任务时自动聚焦输入框
  • 状态持久化:任务状态实时更新
  • 空状态处理:无任务时显示友好提示

安装

pnpm dlx shadcn@latest add http://localhost:3000/r/wuhan/task-list.json

代码演示

只读模式

基础只读模式,展示任务列表。

项目任务已确认
  • 完成项目文档
  • 代码审查
  • 修复 Bug #123
  • 更新依赖包
"use client";

import { useState } from "react";
import {
  TaskList,
  type TodoItem,
} from "@/components/composed/task-list/task-list";

const initialTasks: TodoItem[] = [
  { id: "1", content: "完成项目文档", order: 1 },
  { id: "2", content: "代码审查", order: 2 },
  { id: "3", content: "修复 Bug #123", order: 3 },
  { id: "4", content: "更新依赖包", order: 4 },
];

export function TaskListDefault() {
  const [tasks, setTasks] = useState<TodoItem[]>(initialTasks);

  return (
    <TaskList
      dataSource={tasks}
      title="项目任务"
      status="confirmed"
      editable={false}
      onItemsChange={setTasks}
      onConfirmExecute={() => {}}
    />
  );
}

可编辑模式

可编辑模式,支持任务的增删改。

可编辑模式:点击「修改方案」按钮可以添加、编辑、删除和排序任务

开发任务待确认
  • 设计系统架构
  • 编写技术文档
  • 实现核心功能
"use client";

import { useState } from "react";
import {
  TaskList,
  type TodoItem,
} from "@/components/composed/task-list/task-list";

const initialTasks: TodoItem[] = [
  { id: "1", content: "设计系统架构", order: 1 },
  { id: "2", content: "编写技术文档", order: 2 },
  { id: "3", content: "实现核心功能", order: 3 },
];

export function TaskListEditable() {
  const [tasks, setTasks] = useState<TodoItem[]>(initialTasks);

  return (
    <div className="space-y-2 w-full">
      <p className="text-sm text-muted-foreground">
        可编辑模式:点击「修改方案」按钮可以添加、编辑、删除和排序任务
      </p>
      <TaskList
        dataSource={tasks}
        title="开发任务"
        status="pending"
        editable={true}
        modifyButtonText="修改方案"
        cancelEditButtonText="取消"
        onItemsChange={(newTasks) => {
          setTasks(newTasks);
          console.log("任务列表更新:", newTasks);
        }}
        onConfirmExecute={() => {
          console.log("确认并执行任务:", tasks);
        }}
      />
    </div>
  );
}

带反馈功能

带反馈功能的任务列表。

Pending 状态:显示「修改方案」和「确认并执行」按钮

待执行任务待确认
  • 实现用户认证
  • 添加数据验证
  • 优化性能
  • 编写单元测试
"use client";

import { useState } from "react";
import {
  TaskList,
  type TodoItem,
} from "@/components/composed/task-list/task-list";

const initialTasks: TodoItem[] = [
  { id: "1", content: "实现用户认证", order: 1 },
  { id: "2", content: "添加数据验证", order: 2 },
  { id: "3", content: "优化性能", order: 3 },
  { id: "4", content: "编写单元测试", order: 4 },
];

export function TaskListPending() {
  const [tasks, setTasks] = useState<TodoItem[]>(initialTasks);
  const [executed, setExecuted] = useState(false);

  return (
    <div className="space-y-4 w-full">
      <p className="text-sm text-muted-foreground">
        Pending 状态:显示「修改方案」和「确认并执行」按钮
      </p>
      <TaskList
        dataSource={tasks}
        title="待执行任务"
        status="pending"
        editable={true}
        onItemsChange={setTasks}
        onConfirmExecute={() => {
          setExecuted(true);
          console.log("确认执行任务:", tasks);
        }}
      />

      {executed && (
        <div className="rounded-md border bg-green-50 p-3">
          <p className="text-sm font-semibold text-green-800">
            ✓ 任务已确认执行
          </p>
        </div>
      )}
    </div>
  );
}

Pending 状态

Pending 状态,显示状态标签,支持编辑和确认操作。

学习计划待确认
  • 学习 React 基础
  • 掌握 TypeScript
  • 构建第一个项目
"use client";

import { useState } from "react";
import {
  TaskList,
  type TodoItem,
} from "@/components/composed/task-list/task-list";

const initialTasks: TodoItem[] = [
  { id: "1", content: "学习 React 基础", order: 1 },
  { id: "2", content: "掌握 TypeScript", order: 2 },
  { id: "3", content: "构建第一个项目", order: 3 },
];

export function TaskListPending() {
  const [tasks, setTasks] = useState<TodoItem[]>(initialTasks);

  return (
    <TaskList
      dataSource={tasks}
      title="学习计划"
      status="pending"
      editable={true}
      onItemsChange={setTasks}
      onConfirmExecute={() => {
        console.log("确认执行", tasks);
      }}
    />
  );
}

Confirmed 状态

Confirmed 状态,显示状态标签,隐藏 Footer 按钮,不支持编辑。

学习计划已确认
  • 学习 React 基础
  • 掌握 TypeScript
  • 构建第一个项目
"use client";

import { useState } from "react";
import {
  TaskList,
  type TodoItem,
} from "@/components/composed/task-list/task-list";

const initialTasks: TodoItem[] = [
  { id: "1", content: "学习 React 基础", order: 1 },
  { id: "2", content: "掌握 TypeScript", order: 2 },
  { id: "3", content: "构建第一个项目", order: 3 },
];

export function TaskListConfirmed() {
  const [tasks, setTasks] = useState<TodoItem[]>(initialTasks);

  return (
    <TaskList
      dataSource={tasks}
      title="学习计划"
      status="confirmed"
      editable={true}
      onItemsChange={setTasks}
      onConfirmExecute={() => {
        console.log("确认执行", tasks);
      }}
    />
  );
}

完整功能

完整功能展示,包含编辑、反馈、状态管理。

项目任务列表

当前状态: 待确认

项目开发计划待确认
  • 研究用户需求
  • 制定开发计划
  • 设计 UI/UX
  • 前端开发
  • 后端开发
  • 测试和调试
"use client";

import { useState } from "react";
import {
  TaskList,
  type TodoItem,
} from "@/components/composed/task-list/task-list";
import { Button } from "@/components/ui/button";

const initialTasks: TodoItem[] = [
  { id: "1", content: "研究用户需求", order: 1 },
  { id: "2", content: "制定开发计划", order: 2 },
  { id: "3", content: "设计 UI/UX", order: 3 },
  { id: "4", content: "前端开发", order: 4 },
  { id: "5", content: "后端开发", order: 5 },
  { id: "6", content: "测试和调试", order: 6 },
];

export function TaskListDemo() {
  const [tasks, setTasks] = useState<TodoItem[]>(initialTasks);
  const [status, setStatus] = useState<"pending" | "confirmed">("pending");

  return (
    <div className="space-y-4 w-full">
      <div className="flex items-center justify-between">
        <div className="space-y-1">
          <h3 className="font-semibold">项目任务列表</h3>
          <p className="text-sm text-muted-foreground">
            当前状态:{" "}
            <span
              className={
                status === "pending" ? "text-orange-600" : "text-green-600"
              }
            >
              {status === "pending" ? "待确认" : "已确认"}
            </span>
          </p>
        </div>
        <div className="flex gap-2">
          <Button
            variant="outline"
            size="sm"
            onClick={() => {
              const newStatus = status === "pending" ? "confirmed" : "pending";
              setStatus(newStatus);
            }}
          >
            切换状态
          </Button>
        </div>
      </div>

      <TaskList
        dataSource={tasks}
        title="项目开发计划"
        status={status}
        editable={true}
        modifyButtonText="修改方案"
        cancelEditButtonText="取消编辑"
        onItemsChange={(newTasks) => {
          setTasks(newTasks);
        }}
        onConfirmExecute={() => {
          setStatus("confirmed");
        }}
      />
    </div>
  );
}

API

TaskList

主任务列表组件,封装了只读和编辑两种模式。

Props

PropTypeDefaultDescription
tasksTask[]-任务列表(必填)
onTasksChange(tasks: Task[]) => void-任务变更回调(必填)
editablebooleanfalse是否可编辑
status"pending" | "confirmed"-状态,只支持 pending 和 confirmed,confirmed 状态下不显示 Footer
showFeedbackbooleantrue是否显示反馈按钮
onFeedback(taskId, type) => void-反馈回调
classNamestring-自定义样式类名

Example

import { useState } from "react";
import { TaskList, type Task } from "@/registry/wuhan/composed/task-list";

function TaskManager() {
  const [tasks, setTasks] = useState<Task[]>([
    { id: "1", text: "任务1", completed: false },
    { id: "2", text: "任务2", completed: true },
  ]);

  return (
    <TaskList
      tasks={tasks}
      onTasksChange={setTasks}
      editable
      onFeedback={(taskId, type) => {
        console.log(`Task ${taskId} received ${type} feedback`);
      }}
    />
  );
}

Task

任务数据结构。

PropertyTypeDescription
idstring任务唯一标识(必填)
textstring任务内容(必填)
completedboolean是否已完成(必填)

ReadonlyList

只读模式的任务列表子组件。

Props

PropTypeDefaultDescription
tasksTask[]-任务列表
onToggleComplete(id: string) => void-完成状态切换回调
showFeedbackbooleantrue是否显示反馈按钮
onFeedback(taskId, type) => void-反馈回调

EditableList

编辑模式的任务列表子组件。

Props

PropTypeDefaultDescription
tasksTask[]-任务列表
onTasksChange(tasks: Task[]) => void-任务变更回调

使用场景

  • 待办事项:个人或团队的任务管理
  • 工作流:展示和管理工作流程中的步骤
  • 清单管理:购物清单、检查清单等
  • 任务分配:团队任务的分配和跟踪
  • 项目管理:项目进度和任务跟踪
  • AI 对话:AI 生成的任务列表展示和用户反馈

最佳实践

  1. 状态管理:使用 useState 或状态管理库管理任务列表
  2. 持久化:将任务列表保存到本地存储或后端
  3. 反馈处理:合理使用反馈功能收集用户意见
  4. 键盘操作:提供键盘快捷键提升编辑效率
  5. 验证:对任务内容进行必要的验证(如非空检查)

注意事项

  • 每个任务必须有唯一的 id
  • 编辑模式下任务内容不能为空
  • onTasksChange 回调会返回新的任务列表,需要更新状态
  • 反馈功能需要配合 onFeedback 回调使用

原语组件

Task List 基于以下原语组件构建:

  • TaskListContainerPrimitive - 任务列表容器
  • TaskListHeaderPrimitive - 列表头部
  • TaskItemPrimitive - 单个任务项
  • TaskCheckboxPrimitive - 任务复选框
  • TaskTextPrimitive - 任务文本

这些原语可以在 registry/wuhan/blocks/task-list/task-list-01.tsx 中找到。

键盘快捷键

编辑模式下支持以下快捷键:

快捷键功能
Enter保存当前编辑的任务
Escape取消编辑,恢复原内容
Tab切换到下一个任务

样式定制

组件使用 CSS 变量,可以通过覆盖变量来定制样式:

  • --bg-container: 容器背景色
  • --text-primary: 主文本色
  • --text-secondary: 次要文本色
  • --border-neutral: 边框颜色
  • --gap-md/lg: 间距变量
  • --radius-lg: 圆角大小