Todo list
FreeA checklist an agent or user ticks through, with progress.
pnpm dlx shadcn@latest add https://caliperui.site/r/todo-list.jsonNot started: Read the current table component
Not started: Write the sort helper
Not started: Remove stale snapshots
Not started: Summarise the changes
When to use #
Use it for
- Showing the plan an agent is working through.
- Tracking a short list of steps with a clear done state.
Skip it when
- Items need owners, dates or columns; use a board.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/todo-list.json
Adds its 3 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
import { useState } from "react" import { TodoList, type TodoItem } from "@/components/ui/todo-list" import { type ApprovalStatus, type ToolStatus } from "@/components/ui/approvals" export function TodoListDemo() { const [stage] = useState(0); const [tool] = useState<ToolStatus>("awaiting"); const [approval] = useState<ApprovalStatus>("pending"); const status = (n: number, skipped = false): TodoItem["status"] => (skipped ? "skipped" : stage > n ? "done" : stage === n ? "active" : "pending"); const items: TodoItem[] = [ { id: "read", title: "Read the current table component", status: stage === 0 ? "pending" : tool === "denied" ? (stage > 1 ? "skipped" : "active") : status(1), detail: tool === "denied" ? "Skipped because the file read was not allowed." : undefined }, { id: "write", title: "Write the sort helper", status: status(2) }, { id: "clean", title: "Remove stale snapshots", status: approval === "denied" ? (stage > 3 ? "skipped" : "active") : status(3), detail: approval === "denied" ? "Left in place." : undefined }, { id: "sum", title: "Summarise the changes", status: stage >= 5 ? "done" : stage === 4 ? "active" : "pending" }, ]; return ( <TodoList label="Agent plan" items={items} /> ); }
API reference #
TodoList
component
Accessibility #
It exposes status semantics, with aria-label, aria-expanded, aria-controls and aria-hidden kept in step with state. Changes that matter are announced through a live region.
No custom key handling; Tab and the native activation keys do the work.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.