33-Nano-WebGPU / src /components /ReasoningBlock.tsx
Xenova's picture
Xenova HF Staff
Upload 88 files
f672a5d verified
import { useRef, useState } from "react";
import { Brain, ChevronDown } from "lucide-react";
interface ReasoningBlockProps {
reasoning: string;
isThinking: boolean;
thinkingSeconds: number;
}
export function ReasoningBlock({
reasoning,
isThinking,
thinkingSeconds,
}: ReasoningBlockProps) {
const [open, setOpen] = useState(true);
const prevIsThinkingRef = useRef(isThinking);
// Synchronously collapse when thinking ends (no effect delay).
if (prevIsThinkingRef.current !== isThinking) {
prevIsThinkingRef.current = isThinking;
if (open !== isThinking) {
setOpen(isThinking);
}
}
return (
<div className="mb-3">
<button
onClick={() => setOpen((value) => !value)}
className="flex items-center gap-2 text-xs text-[#c9a84c] hover:text-[#f0f0f0] transition-colors cursor-pointer"
>
<Brain className="h-3.5 w-3.5" />
{isThinking ? (
<span className="font-medium">Thinking…</span>
) : (
<span>Thought for {thinkingSeconds}s</span>
)}
<ChevronDown
className={`h-3 w-3 transition-transform duration-200 ${open ? "" : "-rotate-90"}`}
/>
</button>
{open && (
<div className="mt-2 rounded-lg border border-[#c9a84c33] bg-[#1a1a1a] px-3 py-2 text-xs text-[#888888] whitespace-pre-wrap">
{reasoning}
</div>
)}
</div>
);
}