"use client"; import { Check, ChevronDown, Loader2 } from "lucide-react"; import { AnimatePresence, motion, useReducedMotion } from "motion/react"; import { useId, useState } from "react"; import { cn } from "@/lib/utils"; export type TodoStatus = "pending" | "active" | "done"; export interface TodoItem { id: string; label: string; status: TodoStatus; /** Short detail under the label, such as a file name. */ meta?: string; } export interface TodoListProps { /** Heading shown next to the completion count. Default "Tasks". */ title?: string; items: TodoItem[]; /** Starting expanded state. Default true. */ defaultOpen?: boolean; className?: string; } const EASE = [0.23, 1, 0.32, 1] as const; function StatusMark({ status }: { status: TodoStatus }) { const reduce = useReducedMotion(); const transition = { duration: reduce ? 0 : 0.15, ease: EASE }; return ( {status === "done" ? ( ) : status === "active" ? ( ) : ( )} ); } /** * A collapsible task plan. The header shows how many items are done, and * each status mark morphs as a task moves from pending to active to done. */ export function TodoList({ title = "Tasks", items, defaultOpen = true, className }: TodoListProps) { const [open, setOpen] = useState(defaultOpen); const panelId = useId(); const done = items.filter((item) => item.status === "done").length; return (
    {items.map((item) => (
  • {item.label}

    {item.meta ? (

    {item.meta}

    ) : null}
  • ))}
); }