Todo list
The agent's checklist with a live 3 of 7 count, a hairline progress rail and a check that draws itself when a todo finishes.
On this page
A todo finishes every second or so; the count updates in place and each check draws itself.
Installation
Usage
import { TodoList } from "@/components/ui/chatcn/todo-list"
<TodoList
items={[
{ id: "1", title: "Read the runs layout", status: "done" },
{ id: "2", title: "Add RunsHeaderSkeleton", activeTitle: "Adding RunsHeaderSkeleton", status: "in-progress" },
{ id: "3", title: "Run the tests", status: "pending" },
]}
/>Statuses map one to one onto Claude Code TodoWrite: in_progress is in-progress and completed is done. activeTitle is the present continuous form shown while a todo runs.
Examples
Card and compact
Every status in both variants: done, in progress, blocked, skipped, pending and failed.
Pinned above the composer
With collapsible, the folded header shows the todo in progress and the count. One line of status, the whole list one click away.
Folded to one line that says what is happening now.
Empty and loading
No todos yet, and a list the agent is still writing.
Statuses
| Status | Shows |
|---|---|
pending | A hollow ring: a place in the queue |
in-progress | The spinner, the active title in medium weight |
done | An ink disc whose check draws itself in 180 ms |
blocked | A circled minus and the reason underneath |
skipped | A dashed ring, struck through and dimmed |
failed | A red cross with the word Failed |
cancelled | A stop glyph, dimmed |
Props
| Prop | Type | Notes |
|---|---|---|
items | TodoItem[] | { id, title, activeTitle?, status, detail? } |
title | ReactNode | Defaults to Todos; reads All done when everything settles |
variant | "card" | "compact" | Compact drops into a trace or side rail |
loading | boolean | The agent is still writing the list |
collapsible, open, defaultOpen, onOpenChange | Fold to the current todo | |
empty | ReactNode | Shown with no items |
Keyboard
| Key | Action |
|---|---|
Enter, Space on the header | Fold or unfold a collapsible list |
Accessibility
- Each row starts with a visually hidden status, so the list reads Done: Read the runs layout.
- A polite live region speaks one sentence per change: Done: Add RunsHeaderSkeleton. 3 of 7 done.
- The count uses tabular figures and the rail is decorative; the numbers carry the meaning.
Motion
- When a todo finishes while you watch, the disc swaps in with the 150 ms blur crossfade and its check draws with a 180 ms stroke. A list that mounts finished stays still.
- Text fades to the struck-through color over 150 ms. New todos fade in over 200 ms.
- Under reduced motion the check appears drawn and only fades remain.