StatusTicker
StableOne line that shows the real current step of an AI run, such as Reading 3 files, and keeps its width so nothing beside it moves.
Also known as status updates, live status
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
Steps from the app
const run = ["Reading 3 files", "Checking the return rule", "Writing the draft", "Running tests"];
const [i, setI] = useState(0);
const done = i >= run.length;
<StatusTicker current={done ? "Done in 12s" : run[i]} steps={run} done={done} label="Assistant status" />
<Button size="sm" variant="secondary" onClick={() => setI((n) => Math.min(n + 1, run.length))} disabled={done}>Next step</Button>
<Button size="sm" variant="ghost" onClick={() => setI(0)}>Start again</Button>Press Next step to move the run on, the way an app would when a real step starts. After the last step it settles on a still final line.
When to use it
Tells people what the AI is doing at this moment, in words, without making the layout jump. It only ever shows what the app says is true.
Made of: Line box · Current step · Outgoing step · Live region (hidden)
Use it for
- The current step of an agent run, such as Reading 3 files or Running tests.
- A search or tool call that has a few named steps.
- A final still line when the run ends, such as Done in 12s.
Not for
- A wait with no named steps: use TypingIndicator.
- A fixed summary line at the top of a screen: use StatusLine.
- A short loading state inside a button: use Spinner.
- Marking the surface the AI is changing: use WorkingEdge.
Do and avoid
Do
- Pass the step the app is really on, the moment it starts.
- Keep steps short and plain: a verb and an object, such as Reading 3 files.
- Pass steps or reserve when the ticker sits beside other content.
- End with a still line that says the result, such as Done in 12s.
Avoid
- Do not cycle through steps on a timer to look busy.
- Do not put links or buttons in the line.
- Do not use it for errors that need action.
- Do not show more than one ticker for the same run.
On a phone
- The line never grows wider than its parent: long steps are cut with an ellipsis instead of wrapping.
- It is text only and has no touch targets of its own, so it fits in a narrow header or a chat row.
- Pass steps or reserve so the width is set from the start and the row does not shift on a small screen.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| currentrequired | string | none | The step the run is on right now. When done, pass the final line, such as Done in 12s. |
| steps | string[] | none | Every step text the run may show. Used only to reserve the width of the widest one. It does not drive the line. |
| done | boolean | false | The run has finished. The shimmer stops, the text turns full ink, aria-busy is removed and the line is announced at once. |
| label | string | "AI status" | Accessible name of the line. |
| reserve | string | none | A text whose width the box keeps from the start, such as the longest step you expect. |
| className | string | none | Classes for the outer box. |
"Show code under the preview gives the code for the example on the stage."
In Figma
In Figma, one StatusTicker switches all of this from its properties panel, across 2 variants. Each property sets the React prop beside it, so design and code use the same names.
| Figma property | React | Values |
|---|---|---|
| Done | done | On or off |
| Current | current | 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.
- working
- While done is false the line shimmers softly and carries aria-busy.
- changing
- When current changes, the old line fades out over it while the new one settles in from a 2px blur.
- throttled
- If steps change faster than every 2 seconds, screen readers hear only the latest one when the gap ends.
- truncated
- A step wider than the space it has is cut with an ellipsis instead of wrapping.
- reduced motion
- With reduced motion on, the text swaps with no blur, no fade and no shimmer.
Tokens
Change one of these and every part that uses it follows.
--fg--fg-muted--fg-subtle--dur-base--dur-fast--ease-arrive--ease-in--blur-arrive
Built in
- The line is a group with the label as its name, and carries aria-busy until done is true.
- A separate polite live region announces a new step at most once every 2 seconds. If steps change faster, the latest one is announced when the gap ends.
- When done turns true the final line is announced at once.
- The fading old line and the width placeholders are aria-hidden, so the text is never read twice inside the line.
- Under reduced motion there is no blur, no fade and no shimmer: the text simply changes.
What you need to do
- Pass real steps only. Never cycle through made-up steps on a timer.
- Give a label that says whose status it is, such as Assistant status, when more than one runs on a screen.
- Pass done and a final line, such as Done in 12s, when the run ends, so people hear that it finished.
- Show errors with a proper error message as well. The ticker is not an error surface.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide