Task List
A streaming log of what an agent actually did. Tasks reveal one unit at a time, each animating its own height alongside a short blur and lift, so the thread grows the way the work does instead of jumping. A task shimmers its running title until every step has landed, then settles.
In a chat
The surface it was built for. Sending the message starts the run, the log streams under the user turn, and the answer only arrives once onComplete fires. Keying the list on the turn id gives every send a fresh run.
const [phase, setPhase] = useState("idle");
// The log is keyed on the turn, so each send starts a fresh run.{phase !== "idle" && ( <TaskList key={turnId} tasks={tasks} onComplete={() => setPhase("answered")} />)}Installation
Task List is part of BoardUI Pro.
Dark mode ready - this component follows BoardUI semantic tokens automatically. Set up theme switching.
Resource chips
A step can name the files or resources it touched. Pass chips and each renders inline after the label, with an optional glyph for the file type. Long names truncate rather than wrapping the row.
import { RiReactjsLine } from "@remixicon/react";
const steps = [ { label: "Read", chips: [ { label: "page.tsx", icon: <RiReactjsLine className="size-3.5 text-[#61dafb]" /> }, { label: "layout.tsx", icon: <RiReactjsLine className="size-3.5 text-[#61dafb]" /> }, ], },];Timing and collapse
startDelay holds the first reveal so the log does not land on the same frame as the user turn, and stepInterval paces the rest. Set collapseOnComplete when the log is history rather than the main event; a reader can still open any task by clicking its header.
<TaskList tasks={tasks} startDelay={320} stepInterval={850} collapseOnComplete/>Driving it from real events
An interval is a stand-in. Real steps do not take equal time, so once you have a live stream, pass revealed and advance it as tool calls resolve. The internal timer switches off and every animation stays the same.
// Each task contributes one unit for its header plus one per step, so// `revealed` counts units rather than steps. Drive it from real events// and the internal timer stays out of the way.<TaskList tasks={tasks} revealed={unitsSeen} />