Thinking

Collapsible block for model reasoning and chain-of-thought while a reply is prepared.

Thinking shows extended model reasoning in a collapsible fold. It opens while streaming, tracks duration, shimmers the live label, then settles to a quiet receipt. Manual toggles pin the reader's choice so auto-close never fights them.

The user asked for a release checklist summary.

I should cover changelog review, smoke tests, migrations before cutover, and the first-hour monitors.

Keep the answer short enough to scan during a deploy window.

Installation

pnpm dlx cubix@latest add thinking --base aria

Usage

Import
import {
  Thinking,
  ThinkingContent,
  ThinkingTrigger,
} from "@/components/cubix/thinking"
Example
<Thinking isStreaming={isStreaming}>
  <ThinkingTrigger />
  <ThinkingContent>
    {reasoningText}
  </ThinkingContent>
</Thinking>

Note: Thinking is for one continuous reasoning stream. Render the final answer with Message and Bubble beside it.

Composition

 
Thinking
├── ThinkingTrigger
└── ThinkingContent

Features

  • Auto-opens while the model is thinking
  • Shimmer label during the live stream
  • Measures think duration from isStreaming, or accept a controlled duration
  • Auto-collapses once after the stream ends
  • Manual open or close pins the reader choice
  • Supports controlled open state from outside
  • Stopped, empty, error, and quiet-receipt presentations
  • Fits inside a Message row above the answer bubble

Streaming

Pass isStreaming while tokens arrive. The trigger shows Thinking... with shimmer and the panel stays open.

 

Lifecycle

When streaming ends, duration is recorded and the panel auto-closes after a short delay unless the reader already toggled it.

 

Keep closed while streaming

Set defaultOpen={false} to suppress auto-open. The reader can still expand the fold.

Duration labels

Labels cover active thinking, singular and plural seconds, and the unknown-duration fallback.

Custom label

Override the trigger copy with getThinkingMessage.

The user asked for a release checklist summary.

I should cover changelog review, smoke tests, migrations before cutover, and the first-hour monitors.

Keep the answer short enough to scan during a deploy window.

Inside a message

Place Thinking above the answer bubble inside MessageContent.

The user asked for a release checklist summary.

I should cover changelog review, smoke tests, migrations before cutover, and the first-hour monitors.

Keep the answer short enough to scan during a deploy window.

Start with the changelog, run smoke tests, migrate before cutover, then watch error rate and p95 for the first hour.

Controlled

Drive the fold from outside with open and onOpenChange.

The user asked for a release checklist summary.

I should cover changelog review, smoke tests, migrations before cutover, and the first-hour monitors.

Keep the answer short enough to scan during a deploy window.

Stopped mid-think

If the reader stops generation, keep the partial reasoning and switch the trigger to a stopped receipt.

Empty / waiting

Before the first token, show a waiting panel - or render only the trigger with no content yet.

Waiting for the first reasoning token...

Error

Surface a failed reasoning pass with a destructive label and retry action inside the content.

The model started a reasoning pass, then timed out before a usable plan was ready.

Error: reasoning stream closed after 30s with no final summary.

Quiet receipt

After a completed think, leave the fold collapsed so the chat stays readable. Expand only when the reader wants the details.

Completed think shown as a quiet receipt. Expand to read the reasoning.

API Reference

Thinking

PropTypeDefaultDescription
isStreamingbooleanfalseWhen true, the trigger shows Thinking... and the panel auto-opens unless pinned closed.
openboolean-Controlled open state.
defaultOpenboolean-Initial open state. Defaults to isStreaming. Set false to keep closed while streaming.
onOpenChange(open: boolean) => void-Called when the open state changes. Manual toggles pin the reader's choice.
durationnumber-Controlled think duration in seconds. When omitted, duration is measured from isStreaming.
classNamestring-Additional classes for the thinking root.

ThinkingTrigger

PropTypeDefaultDescription
getThinkingMessage(isStreaming, duration?) => ReactNode-Override the default Thinking... / Thought for Ns label.
childrenReact.ReactNode-Replace the default trigger contents entirely.
classNamestring-Additional classes for the trigger.

ThinkingContent

PropTypeDefaultDescription
childrenReact.ReactNode-Reasoning text or composed content shown while expanded.
classNamestring-Additional classes for the content panel.