ChainOfThought
freeA compact record of the reasoning behind a response for readers who need more context.
Preview
Dark
The request is clear, so the response can focus on the two implementation constraints.
import ChainOfThought from '@/components/composites/ChainOfThought';
export default function UsageDemo() {
return (
<div className="w-full max-w-xl">
<ChainOfThought defaultExpanded>
<p>
The request is clear, so the response can focus on the two
implementation constraints.
</p>
</ChainOfThought>
</div>
);
}Installation
Add this component with the NateUI CLI.
npx nateui@latest add ChainOfThoughtExamples
Labeled Steps
Preview
Dark
Read the request
Identify the required behavior and the boundaries around it.
Check the existing surface
Reuse the project primitives that already own disclosure and text motion.
Choose the smallest change
Keep the timeline local to this component so it stays independent.
import ChainOfThought from '@/components/composites/ChainOfThought';
import { PiCheckCircle, PiClipboardText, PiSparkle } from 'react-icons/pi'
export default function LabeledStepsDemo() {
return (
<div className="w-full max-w-xl">
<ChainOfThought defaultExpanded label="Review trace">
<ChainOfThought.Step
icon={<PiClipboardText />}
label="Read the request"
>
Identify the required behavior and the boundaries around it.
</ChainOfThought.Step>
<ChainOfThought.Step
icon={<PiSparkle className="text-primary" />}
label="Check the existing surface"
>
Reuse the project primitives that already own disclosure and text
motion.
</ChainOfThought.Step>
<ChainOfThought.Step
icon={<PiCheckCircle className="text-success" />}
label="Choose the smallest change"
>
Keep the timeline local to this component so it stays independent.
</ChainOfThought.Step>
</ChainOfThought>
</div>
);
}Streaming
Set isStreaming while content is arriving. The disclosure opens immediately, shimmers its label, and closes after the stream settles unless the reader toggles it.
Preview
Dark
import { useEffect, useState } from 'react';
import ChainOfThought from '@/components/composites/ChainOfThought';
import Button from '@/components/ui/Button';
export default function StreamingDemo() {
const [isStreaming, setIsStreaming] = useState(false);
useEffect(() => {
if (!isStreaming) return;
const timeout = window.setTimeout(() => {
setIsStreaming(false);
}, 2200);
return () => window.clearTimeout(timeout);
}, [isStreaming]);
return (
<div className="w-full max-w-xl space-y-4">
<Button
size="sm"
onClick={() => setIsStreaming(true)}
disabled={isStreaming}
>
Start trace
</Button>
<ChainOfThought isStreaming={isStreaming}>
<ChainOfThought.Step label="Working">
The trace stays open while the next step is being prepared.
</ChainOfThought.Step>
</ChainOfThought>
</div>
);
}API
ChainOfThought
| Prop | Description | Type | Default |
|---|---|---|---|
isStreaming | Forces the disclosure open while content is arriving, shimmers the label, and starts the settle timer when the stream ends. | boolean | false |
defaultExpanded | Opens the disclosure on its first render when it is not streaming. | boolean | false |
label | Replaces the default streaming or settled trigger label. | string | 'Thinking…' while streaming; 'Thought process' otherwise |
className | Classes merged onto the disclosure root. | string | — |
children | Plain content or ChainOfThought.Step rows rendered in the disclosure rail. | ReactNode | — |
ChainOfThought.Step
| Prop | Description | Type | Default |
|---|---|---|---|
icon | Replaces the default dot in the step's marker slot. | ReactNode | Dot marker |
label | Optional heading for the step. | ReactNode | — |
children | Optional supporting content rendered below the label. | ReactNode | — |
className | Classes merged onto the step row. | string | — |
...divProps | Standard <div> attributes forwarded to the step row. | ComponentProps<'div'> | — |