Activity row
The other side at work: its character and one plain line beside it, where its next message will land.
import { ActivityRow } from "@arcadia/ui"The other side is at work. No bubble: its character at 28px and one plain line beside it, where its next message will land. The character is the indicator, so give the AgentAvatar the same state; the label names the step in a few plain words and rolls when the step changes. Any state but idle shimmers the label. meta holds how long the turn has run, in figures that keep their width.
The row is as tall as a one-line bubble, and its character stands --activity-row-px in, on a composer's first control. Under the pointer the character's eyes widen and it leans toward the pointer.
Examples
Steps
A new label rolls in from below as the old one leaves upward, clipped to the line. Pace the changes yourself: a label that stays under about half a second only flickers.
The reply lands
Set leaving when the reply is ready and unmount on onExited.
The row fades and sets back over --duration-exit; a Bubble with enter="land" waits for that and comes in whole. Keep both in one grid cell while they cross, so the list never dips.
States
The eight states of an agent, each with its body clip and its eyes. done and failed play their one move when the state changes, never on mount.
rootStyle takes where the row sits and these knobs: its height and inset as size tokens, and how long its entrance waits.
--activity-row-h- Ref<Control | Space> | `calc(${Ref<Control | Space>} + ${Ref<Space>})`Default calc(var(--control-lg) + var(--space-1))
- The row's height: one line of a conversation's bubbles.
--activity-row-px- Ref<Space>Default var(--space-2)
- Inline padding before the character: it stands on the composer's first control.
--activity-row-enter-delay- Ref<Duration> | "0s"Default 0s
- How long the entrance waits (the row stays hidden until then): a reply's row waits for the sent bubble to land.
With status the row is a polite status region that reads the sentence once per change; the character, the rolling label and the time stay out of it. Without status the whole row is hidden from assistive tech, for a conversation whose live region already says what the agent does.
Nothing in the row takes focus and no input waits on its motion. Reduced motion ends every entrance and exit at once, swaps the label in place and shows it as plain text; the character holds still and its eyes still tell the state.
ActivityRow
avatarrequired- ReactNode
- The character: an
AgentAvatarat 28px, given the samestate(andpoke,enter). label- string | null
- What it is doing, in a few plain words ("Searching the web", or "is thinking" when
whois set). Without it the character alone says it is working: nothing has a name yet. who- string | null
- Who is doing the step: it gives way by whole words, and
labelis the rest ("is thinking"), which never shrinks. state- "idle" | "thinking" | "working" | "composing" | "done" | "failed" | "waiting" | "asleep"Default "working"
- The agent's state: anything but
idleshimmers the label. meta- ReactNode
- A quiet note after the label, in figures that keep their width: the turn's elapsed time.
status- string
- The sentence a screen reader hears ("Juniper is searching the web"): the row becomes a polite status that reads it once per change. Omit when a live region already says so.
enter- ActivityRowEnter | null
- Plays once on mount. Omit for a row that was already there (a reload).
leaving- booleanDefault false
- The row is leaving: it fades and sets back over
--duration-exit, thenonExitedfires. onExited- () => void
- The exit has ended (at once under reduced motion): unmount the row.
rootStyle- RootStyle<ActivityRowKnobs>
- Typed StyleX override: layout and the
--activity-row-*knobs.
Rest props go to HTMLAttributes<HTMLDivElement>.