Reasoning
Collapsible reasoning block with animated expand/collapse. Shows streaming dots while thinking.
Use and inspectUse this as a presentational interface around your own submit, stream, or state handlers. Reset preview only remounts the local example; it does not send a request or connect to a model.Next: inspect the source and wire its callback to a bounded backend action.
ReasoningCollapsible reasoning block with animated expand/collapse. Shows streaming dots while thinking.
"use client";
import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
type ReasoningProps = {
content: string;
isStreaming?: boolean;
defaultOpen?: boolean;
};
export function Reasoning({ content, isStreaming = false, defaultOpen = false }: ReasoningProps) {
const [open, setOpen] = useState(defaultOpen);
return (
<div className="pk-reasoning">
<button className="pk-reasoning-toggle" onClick={() => setOpen(!open)}>
<span className="pk-reasoning-chevron">{open ? "▾" : "▸"}</span>
<span className="pk-reasoning-label">Reasoning</span>
{isStreaming && (
<div className="pk-thinking-dots" style={{ marginLeft: "8px" }}>
<div className="pk-thinking-dot" />
<div className="pk-thinking-dot" />
<div className="pk-thinking-dot" />
</div>
)}
</button>
<AnimatePresence initial={false}>
{open && (
<motion.div
key="reasoning-body"
initial={{ height: 0, opacity: 0 }}
animate={{ height: "auto", opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.2, ease: "easeInOut" }}
style={{ overflow: "hidden" }}
>
<div className="pk-reasoning-inner">{content}</div>
</motion.div>
)}
</AnimatePresence>
</div>
);
}Install
npm install framer-motion
This component requires framer-motion.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
content* | string | — | Reasoning text to display |
isStreaming | boolean | false | Shows animated dots in header when true |
defaultOpen | boolean | false | Whether expanded on mount |