Reasoning
simple-ai/reasoningFreeComponent
A component for displaying AI reasoning content with collapsible sections and streaming support.
Live preview
live · rendered by the registry
Rendered by simple-ai on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://simple-ai.dev/r/reasoning.jsonSource
1"use client";23import { Brain } from "lucide-react";45import { useMemo, useState } from "react";67import {8 Collapsible,9 CollapsibleContent,10 CollapsibleTrigger,11} from "@/components/ui/collapsible";1213import { MarkdownContent } from "@/registry/ui/markdown-content";1415/**16 * Parses reasoning content to extract title and content.17 * Supports formats like:18 * - "**Title**\n\nContent"19 * - "# Title\n\nContent"20 * - "Title\n\nContent" (fallback for plain text with blank line)21 * - Plain text (returns as content with no title)22 */23function parseReasoningContent(text: string): {24 title?: string;25 content: string;26} {27 if (!text || text.trim() === "") {28 return { title: undefined, content: "" };29 }3031 const trimmed = text.trim();3233 // Define matchers for explicit title formats34 const matchers = [35 {36 // Check for markdown bold title format (**Title**)37 pattern: /^\*\*(.+?)\*\*(?:\n\n|\n|$)/,38 },39 {40 // Check for markdown heading format41 pattern: /^#+\s+(.+?)(?:\n\n|\n|$)/,42 },43 ];4445 // Try each matcher in order46 for (const matcher of matchers) {47 const match = trimmed.match(matcher.pattern);48 if (match) {49 const title = match[1].trim();50 const content = trimmed.slice(match[0].length).trim();51 return { title, content: content || trimmed };52 }53 }5455 // Fallback: Check for title/content split (first line as title if followed by blank line)56 const lines = trimmed.split("\n");57 if (lines.length > 1 && lines[1].trim() === "") {58 const title = lines[0].trim();59 const content = lines.slice(2).join("\n").trim();60 return { title, content: content || trimmed };61 }6263 // No title found, return content only64 return { content: trimmed };65}6667interface ReasoningProps {68 content: string;69 isLastPart: boolean;70}7172export function Reasoning({ content, isLastPart }: ReasoningProps) {73 const [isOpen, setIsOpen] = useState(false);7475 const parsedContent = useMemo(76 () => parseReasoningContent(content),77 [content],78 );79 const title = parsedContent.title;80 const finalContent = parsedContent.content;8182 if (isLastPart) {83 return (84 <div className="flex flex-col items-start gap-4 my-2 ml-2 text-muted-foreground">85 <div className="flex items-center gap-2 text-sm">86 <Brain className="size-4" />87 {title ?? "Thinking..."}88 </div>8990 {finalContent.trim() !== "" && (91 <div className="text-sm">92 <MarkdownContent content={finalContent} />93 </div>94 )}95 </div>96 );97 }9899 if (finalContent.trim() === "") {100 return (101// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from simple-ai
All 77 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| base-handlebase-handle | simple-ai | Components | Free | 1 dep | |
| base-nodebase-node | simple-ai | Components | Free | no deps | |
| Chat Inputchat-input | simple-ai | Components | Free | 7 deps | |
| Chat Messagechat-message | simple-ai | Components | Free | no deps | |
| Chat Message Areachat-message-area | simple-ai | Components | Free | 1 dep | |
| Chat Suggestionschat-suggestions | simple-ai | Components | Free | no deps | |
| Editable Handleeditable-handle | simple-ai | Components | Free | 1 dep | |
| Generate Text Nodegenerate-text-node | simple-ai | Components | Free | 1 dep |
