gridland
Components

Chain of Thought

A collapsible component that visualizes AI reasoning steps with animated progress indicators

A collapsible compound component that visualizes AI reasoning steps with animated spinners, status indicators, and optional output content. SDK-agnostic — works with any provider that exposes thinking/reasoning data.

Chain of Thought
?

Run demo

Terminal
bunx @gridland/demo chain-of-thought
Terminal
curl -fsSL https://raw.githubusercontent.com/thoughtfulllc/gridland/main/scripts/run-demo.sh | bash -s chain-of-thought

Installation

Terminal
bunx create-gridland add chain-of-thought

Usage

import {
  ChainOfThought,
  ChainOfThoughtHeader,
  ChainOfThoughtContent,
  ChainOfThoughtStep,
} from "@/components/ui/chain-of-thought"
<ChainOfThought defaultOpen>
  <ChainOfThoughtHeader duration="3.2s" />
  <ChainOfThoughtContent>
    <ChainOfThoughtStep label="Reading files" status="done" />
    <ChainOfThoughtStep label="Planning changes" status="running" isLast />
  </ChainOfThoughtContent>
</ChainOfThought>

Examples

Collapsed

The default state is collapsed — only the header is visible.

Collapsed
<ChainOfThought>
  <ChainOfThoughtHeader duration="3.2s" />
  <ChainOfThoughtContent>
    <ChainOfThoughtStep label="Reading files" isLast />
  </ChainOfThoughtContent>
</ChainOfThought>
Chain of Thought (collapsed)
?

Expanded

Pass defaultOpen to start expanded. Steps show their status indicators.

Expanded
<ChainOfThought defaultOpen>
  <ChainOfThoughtHeader duration="4.3s">Build pipeline</ChainOfThoughtHeader>
  <ChainOfThoughtContent>
    <ChainOfThoughtStep label="Reading codebase" description="src/" status="done" />
    <ChainOfThoughtStep label="Planning changes" description="auth module" status="done" />
    <ChainOfThoughtStep label="Editing files" description="4 files" status="running" />
    <ChainOfThoughtStep label="Running tests" description="vitest" status="pending" isLast />
  </ChainOfThoughtContent>
</ChainOfThought>
Chain of Thought (expanded)
?

Step Output

Pass children to a step to render output content below it with a pipe gutter.

With output
<ChainOfThought defaultOpen>
  <ChainOfThoughtHeader duration="2.1s" />
  <ChainOfThoughtContent>
    <ChainOfThoughtStep label="Reading config" status="done" />
    <ChainOfThoughtStep label="Running tests" description="vitest" status="error">
      FAIL src/auth.test.ts — expected 200, got 401
    </ChainOfThoughtStep>
    <ChainOfThoughtStep label="Fixing auth handler" status="running" isLast />
  </ChainOfThoughtContent>
</ChainOfThought>
Chain of Thought (with output)
?

Custom Header

Pass children to the header to replace the default "Thought for" label.

Custom header
<ChainOfThought defaultOpen>
  <ChainOfThoughtHeader duration="1.8s">Analyzing code</ChainOfThoughtHeader>
  <ChainOfThoughtContent>
    <ChainOfThoughtStep label="Parsing AST" status="done" isLast />
  </ChainOfThoughtContent>
</ChainOfThought>

Custom Icon

Override the default status dot with a custom character.

Custom icon
<ChainOfThought defaultOpen>
  <ChainOfThoughtHeader duration="2.0s" />
  <ChainOfThoughtContent>
    <ChainOfThoughtStep label="Fetching data" icon="↓" status="done" />
    <ChainOfThoughtStep label="Transforming" icon="⚙" status="done" isLast />
  </ChainOfThoughtContent>
</ChainOfThought>

Controlled

Use open and onOpenChange to control the collapsed state externally.

Controlled
const [open, setOpen] = useState(false)

<ChainOfThought open={open} onOpenChange={setOpen}>
  <ChainOfThoughtHeader duration="3.2s" />
  <ChainOfThoughtContent>
    <ChainOfThoughtStep label="Thinking" status="done" isLast />
  </ChainOfThoughtContent>
</ChainOfThought>

Compound Components

ComponentDescription
ChainOfThoughtRoot container with collapsible state
ChainOfThoughtHeaderExpand/collapse arrow with label and duration
ChainOfThoughtContentContent wrapper — renders null when collapsed
ChainOfThoughtStepIndividual step with status dot, label, and optional output

API Reference

ChainOfThought

PropTypeDefaultDescription
openboolean-Controlled open state
defaultOpenbooleanfalseDefault open state (uncontrolled)
onOpenChange(open: boolean) => void-Called when the open state changes
childrenReactNode-Sub-components

ChainOfThoughtHeader

PropTypeDefaultDescription
durationstring-Duration string shown after the label (e.g. "3.2s")
childrenReactNode"Thought for"Custom header text

ChainOfThoughtContent

PropTypeDescription
childrenReactNodeSteps to render when open

ChainOfThoughtStep

PropTypeDefaultDescription
labelstring-Primary label for the step
descriptionstring-Secondary detail shown dimmed after the label
status"done" | "running" | "pending" | "error""done"Step status
iconstring-Custom icon character. Overrides the status-based default
isLastbooleanfalseHide the vertical pipe connector below
childrenReactNode-Output content rendered below the step

ChainOfThoughtStepData

Data type for driving steps from an array (e.g. via .map()).

FieldTypeDescription
labelstringPrimary label for the step
descriptionstringSecondary detail shown dimmed after the label
status"done" | "running" | "pending" | "error"Step status
iconstringCustom icon character
outputstringOutput text shown below the step

Note: The Step type alias is deprecated. Use ChainOfThoughtStepData instead.

Status Indicators

StatusDotColorStyle
donetheme.successNormal
running⠋⠙⠹…theme.primaryBold, animated
pendingtheme.mutedDim
errortheme.errorNormal