Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
Made by shadcn
Edit on GitHub

Trace

Shows the steps an agent takes, such as reasoning, tool calls, sources, and plans, as lines that can expand, link, or open detail.

Trace is a list of lines. Each line has an icon, a title, and an optional description and status. A line can expand to show more detail, link to a page, or open a dialog or sheet.

Every line has the same shape, so reasoning, tool calls, sources, and plans built from Trace look and behave the same. Use Trace for the steps an agent takes inside a turn, Message for its reply, and Marker for notes and dividers between turns.

Installation

npx shadcn@latest add @redpanda/trace
pnpm dlx shadcn@latest add @redpanda/trace
yarn dlx shadcn@latest add @redpanda/trace
bunx shadcn@latest add @redpanda/trace
nubx shadcn@latest add @redpanda/trace
aube dlx shadcn@latest add @redpanda/trace

Usage

import {
  Trace,
  TraceCollapsible,
  TraceCollapsibleContent,
  TraceCollapsibleTrigger,
  TraceDescription,
  TraceIcon,
  TraceLine,
  TraceTitle,
} from "@/components/redpanda-ui/components/trace"

Use a TraceLine for a single step:

<Trace>
  <TraceLine>
    <TraceIcon><SearchIcon /></TraceIcon>
    <TraceTitle>Searched for minimumReleaseAge</TraceTitle>
  </TraceLine>
</Trace>

Wrap the line in a TraceCollapsible to show more detail when it expands:

<Trace>
  <TraceCollapsible>
    <TraceCollapsibleTrigger>
      <TraceLine>
        <TraceIcon><TerminalIcon /></TraceIcon>
        <TraceTitle>Ran node --version</TraceTitle>
      </TraceLine>
    </TraceCollapsibleTrigger>
    <TraceCollapsibleContent>v24.18.0</TraceCollapsibleContent>
  </TraceCollapsible>
</Trace>

Anatomy

Trace
├── TraceLine
│   ├── TraceIcon
│   ├── TraceTitle
│   ├── TraceDescription
│   └── TraceIcon
└── TraceCollapsible
    ├── TraceCollapsibleTrigger
    │   └── TraceLine
    └── TraceCollapsibleContent

TraceLine is always the line. To make a line do something, wrap it in that thing’s trigger: a TraceCollapsibleTrigger, a link, or the trigger of a dialog, sheet, drawer, or popover.

Status

Set status on TraceLine when a step is running, has failed, or hasn’t started yet. A running title shimmers.

Status Use for
none Work that is done: “Ran pnpm install”.
"error" Work that failed. Say so in the title: “Failed to run pnpm lint”.
"running" Work in progress. Write the title in the present tense: “Running pnpm build”.
"pending" Work that has not started, such as a plan step: “Run pnpm test”.

A pending line dims only its icon. The title keeps full contrast, so write it in the imperative to say the work hasn’t started.

Description

Put secondary text such as a diff stat, a duration, or a count in a TraceDescription after the TraceTitle. The title truncates; the description does not.

Collapsible

Put the TraceLine inside TraceCollapsibleTrigger and the detail in TraceCollapsibleContent. The trigger adds a chevron that turns when the row opens.

TraceCollapsibleContent applies className to the detail inside the animated panel. It owns its spacing, so wrap the children in a plain element when they need their own layout:

<TraceCollapsibleContent>
  <div className="flex flex-wrap gap-1.5">
    <Badge variant="outline">vercel.com</Badge>
    <Badge variant="outline">github.com</Badge>
  </div>
</TraceCollapsibleContent>

Open state

Rows start closed. Use defaultOpen on TraceCollapsible to start open, or open with onOpenChange to control a row. The type requires both together, so a controlled row can’t freeze.

To open a row while it streams and let the reader’s click win, pass open ?? running:

const [open, setOpen] = useState<boolean>()

<TraceCollapsible onOpenChange={setOpen} open={open ?? running}>
  <TraceCollapsibleTrigger>
    <TraceLine status={running ? "running" : undefined}>…</TraceLine>
  </TraceCollapsibleTrigger>
  <TraceCollapsibleContent>{text}</TraceCollapsibleContent>
</TraceCollapsible>

Wrap the TraceLine in an anchor. Trace styles any wrapper of a line as its hit and focus target. For a new tab, use an arrow-up-right icon and add “(opens in a new tab)” with sr-only.

<a href="https://docs.astro.build" rel="noreferrer" target="_blank">
  <TraceLine>
    <TraceTitle>
      Install Astro
      <span className="sr-only"> (opens in a new tab)</span>
    </TraceTitle>
    <TraceIcon><ArrowUpRightIcon /></TraceIcon>
  </TraceLine>
</a>

Dialog

Wrap the TraceLine in the dialog’s trigger. The dialog owns its open state, Escape, and focus return.

<Dialog>
  <DialogTrigger>
    <TraceLine>
      <TraceTitle>Searched the web for cache keys</TraceTitle>
      <TraceIcon><ChevronRightIcon /></TraceIcon>
    </TraceLine>
  </DialogTrigger>
  <DialogContent>…</DialogContent>
</Dialog>

Sheet

The same shape as the dialog. Drawer and Popover work the same way.

Sources

A collapsible row whose detail is a Trace of link rows.

Chain of thought

A collapsible row with step rows inside. Set the parent’s status and title from its children. Use keepMounted on the parent’s content so nested rows keep their open state while it is closed.

Whole turn

Three levels: the turn, a summary, and the rows. Text between steps sits between two Trace lists.

Nesting

Trace has no depth limit. A TraceCollapsibleContent can hold another Trace, so the same row nests as deep as the work goes. This preview renders four levels from a recursive tree: the turn, a subagent, a group of commands, and a command with its output.

  • Each level indents 24px and titles truncate, so a deep row never overflows. It just shows less of its title.
  • Put keepMounted on every parent’s TraceCollapsibleContent, so the rows below a closed row keep their open state.
  • Set each parent’s status from its children. A failure anywhere below a row makes it an error row, so a reader can follow it down from the top.
  • Depth is visual only. Rows are disclosure buttons, not a tree, so assistive technology doesn’t announce the level. Past three levels, write titles that make sense on their own, or open the deepest detail in a sheet.

AI SDK parts

The preview at the top of this page renders reasoning, tool-*, and source-url parts from an AI SDK UIMessage, and Replay streams the same turn through useChat. Map each part to a line:

Part Line
reasoning “Thinking” while state is "streaming", then a collapsible “Thought” row.
tool-*, state "output-available" A collapsible “Ran …” row with the output in a CodeBlock.
tool-*, state "output-error" A collapsible “Failed to run …” row with status="error".
tool-*, state "input-streaming", "input-available", or "approval-responded" “Running …” with status="running" while the turn streams. “Waiting to run …” with status="pending" once it stops.
tool-*, state "approval-requested" “Waiting for approval to run …” with status="pending".
tool-*, state "output-denied" “Didn’t run …” with no status.
source-url One link row each, inside a collapsible “Used N sources” row. Untitled sources use the URL’s hostname, or the raw URL.

Switch on every tool state with a never default, so a state added to the AI SDK can’t fall into the error row. A turn that stops while a tool waits for approval hasn’t failed.

The preview’s transport is a fixture. Replace it with your application’s chat endpoint.

Accessibility

Trace adds no roles of its own. Each line gets its semantics from the element that wraps it.

  • A TraceLine on its own is a span. It is read as text and is not a tab stop.
  • Wrapped in a TraceCollapsibleTrigger, it becomes a button with aria-expanded. Wrapped in a link, or in the trigger for a dialog or sheet, it takes that element’s keyboard and focus behavior.
  • TraceIcon is hidden from assistive technology, so TraceTitle is the accessible name. Write it as a sentence that says what happened, like “Edited trace.tsx”, not just “trace.tsx”.
  • Status is shown with color and motion, so put it in the title too: “Running pnpm build” while it runs and “Failed to run pnpm build” when it errors.
  • The shimmer on a running title stops when the reader prefers reduced motion. The title still says what is happening.

API reference

Trace

A list of lines. It also styles any trigger or link that wraps a TraceLine. Accepts all div props.

TraceLine

One line: an icon and a title. It is a span, so it is not a button or a tab stop. Accepts all span props.

Prop Type Default Description
status "running" | "error" | "pending" - The state of the work the line reports.

TraceIcon

A decorative icon slot, hidden from assistive technology. Before the title it names the action; after it, it is the indicator.

TraceTitle

One sentence on one line. It truncates and shimmers while the line is running.

TraceDescription

Secondary text after the title, such as a count or a duration. It does not truncate.

TraceCollapsible

A row that expands. Accepts the props of Collapsible.

Prop Type Default Description
open boolean - The controlled open state. Pass it with onOpenChange.
defaultOpen boolean false Whether the row starts open.
onOpenChange (open: boolean, eventDetails) => void - Called when the open state changes.

TraceCollapsibleTrigger

The button that opens and closes the row. Put a TraceLine inside it. It adds a chevron after the line.

TraceCollapsibleContent

The detail of a row that expands.

Prop Type Default Description
keepMounted boolean false Keep the detail mounted while closed, so nested rows keep their open state.
className string - Classes for the detail inside the animated panel. The panel takes no classes.

Credits

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • minorv0.3.0Add theme-provider component to the registry with documentation and tests. Includes playground type improvements (export RegistryItem, remove as-const boilerplate) and docs site dark mode border color fix.#109
See full history →

Last updated on

Was this page helpful?