Thinking Indicator
Three pockets breathe between recessed and flush while the assistant works — a status region with visible text.
@emboss/thinking-indicator
Thinking…
Searching the registry…
Installation
pnpm dlx shadcn@latest add @emboss/thinking-indicatorUsage
import { ThinkingIndicator } from "@/components/ui/thinking-indicator";
export function Example() {
return <ThinkingIndicator label="Searching…" />;
}API reference
ThinkingIndicator
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | "Thinking…" | Visible status text, also announced to screen readers. |
Source
View source — thinking-indicator.tsxHide source — thinking-indicator.tsx
import { cn } from "@/lib/utils";
/**
* A working state machined into the surface: three pockets breathe between
* recessed and flush while the assistant thinks. Announced through a
* status region; under reduced motion the pockets hold still and the text
* carries the meaning.
*
* @example
* <ThinkingIndicator label="Searching the registry…" />
*/
function ThinkingIndicator({
className,
label = "Thinking…",
...props
}: React.ComponentProps<"div"> & {
/** Visible status text; also announced to screen readers. */
label?: string;
}) {
return (
<div
data-slot="thinking-indicator"
role="status"
className={cn(
"inline-flex items-center gap-2.5 rounded-lg bg-well px-4 py-2.5 shadow-deboss-1",
className,
)}
{...props}
>
<span aria-hidden className="flex items-center gap-1">
{[0, 1, 2].map((index) => (
<span
key={index}
className="relative size-1.5 rounded-full bg-well-deep shadow-deboss-1"
>
<span
className="absolute inset-0 animate-depth-pulse rounded-full bg-surface-2 shadow-flush"
style={{ animationDelay: `${index * 200}ms` }}
/>
</span>
))}
</span>
<span className="text-sm text-ink-muted">{label}</span>
</div>
);
}
export { ThinkingIndicator };