ActivityTrace
StableThe agent's work shown step by step, each step tagged with who did it, then folded to one line.
Also known as activity feed, trace, steps log
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
Folded, then open
- Done
Read your messageAI
You said the kettle arrived with a cracked lid. - Done
Looked up the return windowRule sheet
Damaged items can be returned within 30 days. - Done
Worked out the refundCalculated
₹2,340 minus ₹0 shipping = ₹2,340 - Done
Checked the amount against the orderSafety check
const steps = [
{ id: "1", actor: "ai", title: "Read your message", detail: "You said the kettle arrived with a cracked lid." },
{ id: "2", actor: "rule", title: "Looked up the return window", detail: "Damaged items can be returned within 30 days." },
{ id: "3", actor: "calculated", title: "Worked out the refund", detail: "₹2,340 minus ₹0 shipping = ₹2,340" },
{ id: "4", actor: "check", title: "Checked the amount against the order" },
];
<div className="space-y-3">
<ActivityTrace steps={steps} summary="Read your message · 4 steps" />
<ActivityTrace steps={steps} summary="Read your message · 4 steps" defaultOpen />
</div>Folded, the trace is one line. Press it to see every step. The second trace starts open.
When to use it
Show how an answer was reached without filling the thread. The tag on each step tells the reader how much to trust it: an AI judgment can be wrong, a rule sheet lookup was checked, a calculation was done by code, and a safety check is a guardrail.
Made of: Summary button with chevron · Step list · Status icon · Step title · Actor tag · Detail
Use it for
- An agent that reads, looks things up and calculates before it answers.
- A thread that must stay short once the work is finished.
- Showing which steps were the AI's judgment and which were fixed rules or code.
Not for
- A plan the person approves step by step: use StepTimeline.
- One tool call with its input and result: use ToolCallCard.
- The model's free-form reasoning text: use ThinkingBlock.
- Any content that only needs to open and close: use Collapsible.
Do and avoid
- Done
Read your messageAI
- Done
Found the refund rule for damaged itemsRule sheet
- Done
Worked out the reply deadlineCalculated
- Done
Read your messageAI
- Done
Thinks the seller has 30 days to replyRule sheet
- Done
Guessed you paid about ₹2,300Calculated
Do
- Tag every step honestly. Use AI only for judgments the model made.
- Fold the trace when the work ends so the thread stays short.
- Keep titles to one short line and put extra words in detail.
- Show a failed step and say what failed.
Avoid
- Do not tag a model guess as Rule sheet or Calculated. That would make it look more certain than it is.
- Do not use it for steps the person must approve. Use StepTimeline or ApprovalPrompt.
- Do not put long reasoning text in a step. Use ThinkingBlock.
- Do not rely on the status icon colour alone. Keep the words.
On a phone
- The summary row is at least 44px tall on touch screens and spans the full width.
- Summaries, step titles and details wrap onto new lines instead of being cut off.
- Opening and closing needs a tap, not hover.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| stepsrequired | { id: string; actor: "ai" | "rule" | "calculated" | "check" | "you"; title: string; detail?: ReactNode; status?: "pending" | "running" | "done" | "failed" }[] | none | The steps in order. status defaults to done. |
| summaryrequired | string | none | The one line shown when folded, such as "Read your message · 8 steps". It is also the button's name. |
| streaming | boolean | none | True while steps are still arriving. The list is held open, new rows slide in (when motion is allowed) and each new step is announced. |
| defaultOpen | boolean | false | Start open. Ignored when open is passed. |
| open | boolean | none | Controlled open state. |
| onOpenChange | (open: boolean) => void | none | Called when the person opens or folds the list. |
| actorLabels | Partial<Record<TraceActor, string>> | none | Rename the tags. The defaults are AI, Rule sheet, Calculated, Safety check and You. |
| className | string | none | Extra classes for the outer box. |
"Show code under the preview gives the code for the example on the stage."
In Figma
In Figma, one ActivityTrace switches all of this from its properties panel, across 16 variants. Each property sets the React prop beside it, so design and code use the same names.
| Figma property | React | Values |
|---|---|---|
| Streaming | streaming | On or off |
| Open | open | On or off |
| State | Hover, Pressed and Focus come from the browser. | Default, Hover, Pressed, Focus |
| Summary | summary | Any text |
States
States this part has beyond its default look. Build each one your screen can reach. States set by a property are in the Code tab.
- folded
- Only the summary line shows, with the chevron pointing right and aria-expanded false.
- open
- The step list shows under the summary and the chevron turns down.
- streaming
- The list is held open, the summary button ignores presses, and each new row slides in and is announced politely.
- step running
- A step with status running shows a spinner (still when motion is reduced) and the word Running for screen readers.
- step failed
- A failed step shows an X, the word Failed and a danger-coloured title.
- step pending
- A pending step shows an empty circle and a muted title.
- focus
- A visible focus ring appears on the summary button.
- hover
- The summary row gets a soft background under the pointer when not streaming.
Tokens
Change one of these and every part that uses it follows.
--surface--border--border-strong--fg-muted--fg-subtle--success-fg--danger-fg--surface-hover--dur-fast--animate-rise--lime--radius-card
Built in
- The folded line is a real button with aria-expanded and aria-controls, and the chevron is decorative.
- Steps are an ordered list. Each status icon has a word for screen readers: Waiting, Running, Done or Failed. A failed step also shows the word Failed.
- Each step has a text tag, so who did it is never shown by colour alone.
- While streaming, a polite live region reads out each new step once. A trace that mounts already full is not read out.
- While streaming, the button is marked aria-disabled and the list stays open.
- The spinner and sliding rows only move when the system allows motion. The button is 44px tall on coarse pointers.
What you need to do
- Write step titles as short sentences that make sense when read out one after another.
- Keep summary specific, such as "Read your message · 8 steps", because it is the button's name.
- Set status on every step while streaming, so the running one is marked.
- Set streaming back to false when the work ends, so the person can fold the list.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide