# Tool Call Row

> An animated tool call row for React and shadcn, showing an AI agent's tool call with its input and output.

A tool call as a flush row: while it runs a band of light travels down its left rule and the seconds roll; when it lands the check draws and the result count rolls up; an error shakes it once. Click to see the input and output, or fold several calls into one line.

- Tier: Eased Pro
- Interaction: Loading
- Page: https://eased.dev/components/tool-call-row
- Installs: motion, @base-ui/react

## Install

Tool Call Row ships with Eased Pro (https://eased.dev/#pricing). Members add the `@eased-pro` registry with their token (https://eased.dev/account), then run:

```bash
npx shadcn add @eased-pro/tool-call-row
```

A tool call as a flush row, not a card: a status mark, a label and a muted detail, with the count and duration in a trailing column. Expandable to the input and output on Base UI Collapsible.

## When to use

- Showing what an agent called inside a chat reply or a run timeline.
- Several calls in a row: wrap them in `ToolCallGroup` so they fold into "Ran 3 tools".

## When not to use

- A call that needs a decision: show an [Approval Card](/components/approval-card) for it.
- A whole multi-step run: use [Agent Run](/components/agent-run), which renders these rows inline.

## Usage

```tsx example.tsx
import { ToolCallRow } from "@/components/eased/tool-call-row/tool-call-row";
import { toolStateFromPart } from "@/components/eased/_primitives/thinking-core/thinking-core";

<ToolCallRow
  name="search_flights"
  label="Searching flights"
  doneLabel="Searched flights"
  detail="SFO → JFK · Nov 3"
  state={toolStateFromPart(part)}
  count={part.output?.results}
  input={part.input}
  output={part.output}
/>
```

## API reference

### ToolCallRow

| Prop | Type | Default | Description |
|---|---|---|---|
| `name` | `string` | | The tool's name; shown when expanded and announced. |
| `state` | `ToolState` | | `pending`, `awaiting-approval`, `running`, `done`, `error` or `denied`. |
| `label` / `doneLabel` | `string` | `name` / `label` | The line while it runs and once done. |
| `detail` | `ReactNode` | | Muted second part of the line. |
| `count` / `countLabel` | `number` / `string` | / `"results"` | Rolls up from 0 when the call lands. |
| `durationMs` | `number` | | Shown once settled. |
| `startedAt` | `number` | | Epoch ms; live seconds roll while running. |
| `input` / `output` / `errorText` | `unknown` / `unknown` / `string` | | Shown as JSON when expanded. Without them the row is not a button. |
| `icon` | `ReactNode` | wrench | 16px glyph while running. |
| `open` / `defaultOpen` / `onOpenChange` | | `false` | Expanded state. |
| `announce` | `boolean` | `true` | The row's own live region. Pass `false` inside a surface that announces the run, so a rail of rows does not read "web_search: queued" for each. |

### ToolCallGroup

`children` (rows), `states: ToolState[]` (for the summary line), `defaultOpen`.

## Keyboard

| Key | Action |
|---|---|
| `Enter` / `Space` | Expands or collapses a row or group. |

## Accessibility

- An expandable row is a disclosure button (`aria-expanded`). Each row keeps a visually hidden status that announces "search_flights: done, 14 results".

## Motion

Running: a band of light travels down the row's 1px left rule on a 1.1s loop (transform only), paused off-screen. Done: the mark swaps with y + blur, the check draws on the snappy spring and the count rolls up from 0. Error: the row shakes once, 6px, settling over 400ms. Panels open on Auto Height. Reduced motion: the trail is a still, darker rule; marks fade; no shake.

## Notes for AI

Map AI SDK tool parts with `toolStateFromPart`, pass human labels (present tense while running, past once done) and a count when the output has one.

Do not wrap rows in cards or add your own spinner: the left rule is the running state (rule 95).

## Related

- [Agent Run](/components/agent-run): a rail of steps with these rows inline.
- [Approval Card](/components/approval-card): for calls in `awaiting-approval`.
