ThoughtChain

The steps an agent took on the way to an answer, each with a status, and details you can fold.

Accessibility

What ThoughtChain does for you, and what it leaves to the page around it.

What ThoughtChain renders

The chain is a stack of <div>s with no role: no list, no headings, no landmark. A screen reader reads the steps as text in order, title, description, content and footer, with nothing to say where one step ends and the next begins.
  • Put a visible heading above the chain, like “Steps taken”, so a reader moving by headings can find it and skip it.
  • Write each title so it reads on its own. “Searched the web” works out of context, and “Step 2” does not.
  • The default step numbers are drawn as text, so they are read out. A custom icon from the kit's Icon is hidden from screen readers.

Status is silent

The status glyphs are decorative: they are hidden from screen readers and have no text of their own. A reader who cannot see the spinner, the check or the error mark gets no status at all.
  • Write the outcome into the title or the description: “Searching 3 sources” while it runs, “Search failed” when it errors, “Stopped” for abort.
  • error tints the step red, which is a second signal for sighted readers but not for readers with a color vision deficiency. The words carry it.

Announcing progress

The chain is not a live region. A step that appears or changes from loading to success while the reader is elsewhere on the page says nothing.
  • Add one short polite region of your own next to the chain, and write a summary into it as the run moves on: “Searching the web”, then “Done, 3 steps”.
  • Do not put aria-live on the chain itself. Every content update would be read out in full, and a streaming run updates many times a second.
<div role="status" className="sr-only">{summary}</div>

Collapsible steps and the keyboard

A collapsible step's title is a clickable <div>. It takes no focus, has no button role and no aria-expanded, so a keyboard user cannot open it and a screen reader does not know it opens.
  • Control the chain with expandedKeys, and pass a real <button type="button"> as the step's title, with aria-expanded set from your state. Its click reaches the title, which toggles the step, so give the button no click handler of its own.
  • Enter and Space on that button fire the same click, so the keyboard works with no extra code.
  • Closed content unmounts by default, so it is gone from the accessibility tree too. That is what a reader expects of a closed section.
1
{
2
key: "search",
3
collapsible: true,
4
title: (
5
<button type="button" aria-expanded={open.includes("search")}>
6
Searched the web
7
</button>
8
),
9
content: results,
10
}

Blink and reduced motion

blink sweeps a gradient across the title, and keeps sweeping until you remove it. It does not check whether the reader has asked for reduced motion.
  • Set blink only while a step runs, and only when prefers-reduced-motion is not set. The loading spinner already says the step is running.
  • While it blinks, the title is drawn in the lighter description color. Check that the running step's title still reads against the background in your theme, in light and dark mode.

Contrast

Descriptions use the theme's description color, which is lighter than body text. On a solid ThoughtChain.Item it also sits on a gray fill.
  • Keep anything the reader needs in the title, and use the description for detail that can be missed.
  • Every color here comes from the active theme, so check a custom seed yourself. The Tokens tab lists the colors ThoughtChain reads.