A thinking disclosure that opens itself while a reasoning stream is live and closes shortly after the stream ends.
1
2
3'use client';
import { useState, type ReactNode } from 'react';Installation#
pnpm dlx shadcn@latest add https://ui.zeroxsolutions.com/r/reasoning-collapsible.jsonUsage#
import {
ReasoningCollapsible,
ReasoningCollapsibleContent,
ReasoningCollapsibleTrigger,
} from '@/components/layout/reasoning-collapsible';
import { useReasoningCollapsible } from '@/hooks/use-reasoning-collapsible';function ReasoningLabel() {
const { streaming, duration } = useReasoningCollapsible();
return streaming ? 'Thinking...' : `Thought for ${duration ?? 'a few'} seconds`;
}
<ReasoningCollapsible streaming={isLive}>
<ReasoningCollapsibleTrigger>
<ReasoningLabel />
</ReasoningCollapsibleTrigger>
<ReasoningCollapsibleContent>
<MarkdownView>{text}</MarkdownView>
</ReasoningCollapsibleContent>
</ReasoningCollapsible>;The label and the body are the consumer's; useReasoningCollapsible hands the label its timing. It opens
while streaming is true (unless defaultOpen is false) and closes about a second after the stream
ends, once only, so a reader who reopens old reasoning keeps it open. useReasoningCollapsible() returns
{ streaming, isOpen, duration } from inside a <ReasoningCollapsible>; duration is the last stream's
whole seconds, rounded up, undefined until one has ended, and it throws outside one.
Composition#
ReasoningCollapsible
|-- ReasoningCollapsibleTrigger
`-- ReasoningCollapsibleContent
`-- MarkdownViewAPI reference#
ReasoningCollapsible#
Renders shadcn's Collapsible and takes every
prop it takes except open, plus:
| Prop | Type | Default |
|---|---|---|
streaming | boolean | false |
defaultOpen | boolean | value of streaming |
A thinking / reasoning disclosure. It opens while streaming is true (unless defaultOpen is false),
closes itself once about a second after the stream ends, and carries data-streaming while streaming. It
sets data-slot="reasoning-collapsible".
ReasoningCollapsibleTrigger#
Renders shadcn's CollapsibleTrigger, as a
full-width ghost Button, and takes every prop it
takes. The toggle row; children are the label, which pulses while the root is streaming. Its brain and
chevron icons play while the row is hovered or focused, and the chevron turns over while the body is open.
It sets data-slot="reasoning-collapsible-trigger".
ReasoningCollapsibleContent#
Renders shadcn's CollapsibleContent and takes
every prop it takes. The reasoning body, in muted text under the trigger; unmounted while closed. It sets
data-slot="reasoning-collapsible-content".