AI Tool Call Card
A status card for an AI tool call that transitions smoothly between running / success / error, and expands to show the arguments and result.
This is a WebberUI Pro component
Free during the launch campaign: sign up or sign in, then hit “Copy install command” in the preview above and it installs straight away — no payment, no credit card. The command below returns 401 while you are signed out.
npx shadcn@latest add "https://webberui.com/r/ai-tool-call-card.json?t=<install token>"Playground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<AiToolCallCard />
Installation
npx shadcn@latest add "https://webberui.com/r/ai-tool-call-card.json?t=<install token>"Or, once registries are configured in components.json, install it as @webberui/ai-tool-call-card.
Usage
import { AiToolCallCard } from "@/components/ui/ai-tool-call-card";
<AiToolCallCard
name="search_web"
status="running"
description="Search the document library to answer the user's question"
args={{ query: "webber ui motion", top_k: 5 }}
/>;status is driven by your agent's execution flow, and the card transitions automatically as the value changes: the circular indicator's icon pops in, the status text flips vertically, and the border color tints smoothly.
Status transitions
Just bind status to the tool call's real lifecycle and the component handles every transition animation:
const [status, setStatus] = useState<ToolCallStatus>("pending");
async function call() {
setStatus("running");
try {
const result = await runTool();
setStatus("success");
} catch {
setStatus("error");
}
}On entering error, uncontrolled mode expands automatically to reveal the error message.
Expanding the arguments and result
The card can expand when args is provided; result (on success) and error (on failure) are shown in their respective sections. The expanded state supports controlled and uncontrolled modes:
<AiToolCallCard
name="run_sql"
status="success"
args={{ table: "orders", limit: 100 }}
result={<pre>{JSON.stringify(rows, null, 2)}</pre>}
expanded={open}
onExpandedChange={setOpen}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | — | Tool (function) name, shown in a monospace face |
status | "pending" | "running" | "success" | "error" | — | The current status; changing it triggers the transition animation |
label | string | Per status | Overrides the status text on the right |
description | string | — | A one-line subtitle beneath the name |
args | Record<string, unknown> | — | Call arguments, shown as a monospace key/value list |
result | React.ReactNode | — | Shown in the "Result" section on success |
error | React.ReactNode | — | Shown in the "Error" section on failure |
elapsedMs | number | — | Elapsed time (ms), formatted next to the status text |
expanded | boolean | — | Controlled expanded state |
defaultExpanded | boolean | false | Initial expanded state in uncontrolled mode |
onExpandedChange | (expanded: boolean) => void | — | Callback when the expanded state changes |
How it works
- The circular indicator swaps icons by
statusthroughAnimatePresence: the old icon shrinks away and the new one springs in - The status text uses a flip window (an overflow mask), with the old value flipping out upward and the new one flipping in from below
- The border and the indicator's base color tint smoothly via
transition-colors(var(--wb-duration-normal,300ms)) - While running, an indeterminate bright band sweeps along the bottom line, signalling that the tool is still working
- The expandable area opens and closes with a
height: autotransition, and the content fades in
Accessibility
- The card contains plain text with
role="status"andaria-live="polite", announcing "name: status" whenever the status changes - Every animated node is
aria-hidden, so nothing is announced twice - When expandable, the header row is a
<button>carryingaria-expanded/aria-controls, supporting keyboard operation and a focus ring - When the user has "reduce motion" enabled: the indicator stops spinning, the flip becomes a fade in / fade out, the progress band is hidden, and expanding switches instantly — while the DOM structure stays consistent (the switch happens only after mount, avoiding a hydration mismatch)
AI Reasoning Panel
A collapsible panel for an AI's thinking process — expanding automatically while thinking, with a shimmering title and step-by-step reveal, then totalling the elapsed time and optionally collapsing itself.
AI Model Picker
A model dropdown picker with capability star ratings, speed / cost badges, and a recommended tag.