Components
ToolCallCard
Unstable: an action the AI is taking in the product, shown step by step, with its status and a scoped retry when a step fails. Import it from @nizivo/react/unstable/tool-call-card.
Examples
Basic
Three states of one action: running, done, and failed with a scoped retry.
- Find posts from last week, done
- Match products by name, in progress
- Apply tags, not started
- Find posts from last week, done
- Match products by name, done
- Apply tags, done
- Find posts from last week, done
- Match products by name, done
- Apply tags — Instagram rejected 1 post, failed
import type { JSX } from 'react';
import { Button } from '@nizivo/react/button';
import { ToolCallCard } from '@nizivo/react/unstable/tool-call-card';
export function ToolCallCardExample(): JSX.Element {
return (
<div style={{ display: 'grid', gap: 16, maxInlineSize: 460 }}>
<ToolCallCard
title="Tag products on 3 posts"
status="running"
steps={[
{ label: 'Find posts from last week', status: 'done' },
{ label: 'Match products by name', status: 'running' },
{ label: 'Apply tags', status: 'todo' },
]}
/>
<ToolCallCard
title="Tag products on 3 posts"
status="done"
steps={[
{ label: 'Find posts from last week', status: 'done' },
{ label: 'Match products by name', status: 'done' },
{ label: 'Apply tags', status: 'done' },
]}
/>
<ToolCallCard
title="Tag products on 3 posts"
status="failed"
steps={[
{ label: 'Find posts from last week', status: 'done' },
{ label: 'Match products by name', status: 'done' },
{ label: 'Apply tags — Instagram rejected 1 post', status: 'failed' },
]}
actions={
<Button variant="secondary" size="sm">
Retry failed step
</Button>
}
/>
</div>
);
}
Import
import { ToolCallCard } from '@nizivo/react/unstable/tool-call-card';
// Once per app (Getting started), after
// @nizivo/tokens/tokens.css and @nizivo/react/css/base.css
import '@nizivo/react/css/tool-call-card.css';Static or interactive
Server. No client JavaScript; a retry is a Button you pass in
actions. How to choose.
Status
status is the whole action's: running (a spinner, and the card is aria-busy), done or
failed (a critical edge). The pill always carries a word as well as its mark, so the state never
rests on colour; under Reduced motion the spinner stands still.
Steps
steps is the plan, in order: each has a label and a status (todo, running, done,
failed). A screen reader hears each step's status after its label ("Apply tags, failed"). For a
failure, say which step and why in its label, and offer a retry of that step, not of the whole
action. Never hide an action the AI took.
Props
Server component Renders data-slot="tool-call-card" with the class nz-tool-call-card. Props: ToolCallCardProps. Source: src/unstable/tool-call-card/tool-call-card.tsx.
| Name | Type | Default | Description |
|---|---|---|---|
actions | ReactNode | – | Under the steps, for example a Button that retries the failed step. |
labels | Partial<ToolCallCardLabels> | – | |
render | RenderProp<Record<string, never>> | – | Must render a |
statusrequired | ToolCallStatus"running""done""failed" | – | |
stepsrequired | readonly ToolCallStep[] | – | The plan, in order. |
titlerequired | ReactNode | – | What the AI is doing, as a short action: "Tag products on 3 posts". |
- Also takes every attribute of
<div>exceptchildren,title. (Omit<ComponentPropsWithRef<"div">, "title" | "children">)
render takes an element, or, in client code, a function of the props and no state.
Other exports
ToolCallCardLabelstypeimport type { ToolCallCardLabels } from '@nizivo/react/unstable/tool-call-card'ToolCallCard's own strings (§16.4): serialisable, English defaults.
Name Type Default Description donerequiredstring'Done'failedrequiredstring'Failed'runningrequiredstring'Running'stepDonerequiredstring'done'stepFailedrequiredstring'failed'stepRunningrequiredstring'in progress'stepTodorequiredstring'not started'A step not started yet, read after its label.
ToolCallCardPropstypeimport type { ToolCallCardProps } from '@nizivo/react/unstable/tool-call-card'The props of
ToolCallCard, listed above.ToolCallStatustypeimport type { ToolCallStatus } from '@nizivo/react/unstable/tool-call-card'The whole action's status.
type ToolCallStatus = "running" | "done" | "failed"ToolCallSteptypeimport type { ToolCallStep } from '@nizivo/react/unstable/tool-call-card'Name Type Default Description labelrequiredReactNode– What the step does: "Find posts from last week"; for a failure, also why.
statusrequiredToolCallStepStatus"todo""running""done""failed"– ToolCallStepStatustypeimport type { ToolCallStepStatus } from '@nizivo/react/unstable/tool-call-card'One step's status.
type ToolCallStepStatus = "todo" | "running" | "done" | "failed"
Data attributes and slots
Style parts by class (.nz-<slot>) and state by data attribute. Attribute meanings come from contracts/vocabulary.json.
| Slot | Rendered by | Data attributes |
|---|---|---|
tool-call-card.nz-tool-call-card | ToolCallCardroot (takes render) |
|
tool-call-card-status.nz-tool-call-card-status | ToolCallCardinner element (CSS only) | none |
tool-call-card-status-text.nz-tool-call-card-status-text | ToolCallCardinner element (CSS only) | none |
tool-call-card-step.nz-tool-call-card-step | ToolCallCardinner element (CSS only) |
|
tool-call-card-steps.nz-tool-call-card-steps | ToolCallCardinner element (CSS only) | none |
tool-call-card-title.nz-tool-call-card-title | ToolCallCardinner element (CSS only) | none |
CSS hooks
Set a hook on the component's class or any ancestor to restyle it without specificity games; leave it unset for the default shown.
| Hook | Default | Read as |
|---|---|---|
--nz-tool-call-card-bg | --nz-bg-surface |
|
--nz-tool-call-card-radius | --nz-radius-xl |
|
Layers: nz.components. Classes: .nz-glyph-spinner, .nz-tool-call-card, .nz-tool-call-card-actions, .nz-tool-call-card-header, .nz-tool-call-card-icon, .nz-tool-call-card-status, .nz-tool-call-card-status-icon, .nz-tool-call-card-status-text, .nz-tool-call-card-step, .nz-tool-call-card-step-icon, .nz-tool-call-card-steps, .nz-tool-call-card-title, .nz-tool-call-card-todo.
Tokens this stylesheet reads (30)
--nz-bg-accent-subtle, --nz-bg-critical-subtle, --nz-bg-muted, --nz-bg-success-subtle, --nz-bg-surface, --nz-border-control, --nz-border-critical, --nz-border-subtle, --nz-border-width-default, --nz-duration-spin, --nz-font-body-s, --nz-font-label-m-strong, --nz-font-label-s, --nz-icon-brand, --nz-icon-success, --nz-radius-full, --nz-radius-sm, --nz-radius-xl, --nz-size-icon-sm, --nz-space-0-5, --nz-space-1, --nz-space-1-5, --nz-space-2, --nz-space-4, --nz-space-8, --nz-text-critical, --nz-text-primary, --nz-text-secondary, --nz-text-success, --nz-text-tertiary
Accessibility
Nothing in this component takes focus or keyboard input.
Keyboard
None.
Toast
A short message after an action, bottom-centre, with one optional action. toast() shows it from anywhere in your client code; one <Toaster /> in the root layout renders the stack and speaks each message to screen readers.
Tooltip
A short label shown on hover and keyboard focus, on an inverse surface. The trigger can be any focusable element, a server Button included.