Reasoning
A collapsible "chain of thought" disclosure that tracks streaming duration and splits text into labelled sections.
Check the existing layout, then decide which axis needs centering.
Confirm the element centers both horizontally and vertically.
Usage guidelines
- Chain-of-thought disclosure — a collapsible block for a model's thinking.
- Live label — shimmers "Thinking…" while streaming and settles to "Thought for Ns" when it stops; the duration is tracked for you.
- Sectioned content — bold
**Header**lines split the text into labelled sections, rendered as markdown. - State via
useReasoning— read streaming, open, and duration from anywhere inside. - Get started — see Installation to add the package and copy the component.
Anatomy
<Reasoning isStreaming={isStreaming}>
<Reasoning.Trigger />
<Reasoning.Content>{reasoningText}</Reasoning.Content>
</Reasoning>Driven from a streaming message, passing the reasoning parts' text:
<Reasoning isStreaming={isLast && isStreaming} defaultOpen={false}>
<Reasoning.Trigger label={headers} />
<Reasoning.Content>{texts}</Reasoning.Content>
</Reasoning>useReasoning
Read the disclosure state from anywhere inside <Reasoning>:
| Prop | Type | Default |
|---|---|---|
isStreaming | boolean | — |
isOpen | boolean | — |
setIsOpen | (open: boolean) => void | — |
duration | number | undefined | — |
Accessibility
Built on a disclosure: Reasoning.Trigger is a <button> with aria-expanded
and aria-controls pointing at the panel, so screen readers announce the
collapsed/expanded state and the relationship. While isStreaming, the root
carries aria-busy so assistive tech knows the content is still updating.
API reference
Every part accepts className, style, and render (see
PrimitiveProps) and emits a bespoke part attribute (data-<part>) unless noted.
Reasoning
The disclosure root. Renders data-reasoning.
| Prop | Type | Default |
|---|---|---|
isStreaming | boolean | false |
duration | number | — |
defaultOpen | boolean | false |
open | boolean | — |
onOpenChange | (open: boolean) => void | — |
| Attribute | Description |
|---|---|
data-reasoning | The disclosure root. |
data-streaming | Present while isStreaming is true. |
data-open | Present while open. |
data-closed | Present while closed. |
Reasoning.Trigger
The toggle. Renders a <button> with data-reasoning-trigger. Without
children it shows the default thinking/thought message.
| Prop | Type | Default |
|---|---|---|
label | string[] | — |
getThinkingMessage | (isStreaming, duration?, label?) => { key, component } | — |
children | ReactNode | — |
| Attribute | Description |
|---|---|
data-reasoning-trigger | The toggle button. |
data-open | Present while open. |
data-closed | Present while closed. |
Reasoning.Content
The collapsible panel. Renders data-reasoning-content. Bold **Header**
lines split the text into sections rendered as markdown.
| Prop | Type | Default |
|---|---|---|
children | string | string[] | (required) |
keepMounted | boolean | false |
| Attribute | Description |
|---|---|
data-reasoning-content | The panel. |
data-open | Present while open. |
data-closed | Present while closed. |
data-starting-style | Present on the first open frame (enter transition). |
data-ending-style | Present while the exit animation runs. |