05 / 37 · Reasoning
Typing indicator
The classic three dots, tuned to read as presence rather than noise.
Installation
npx shadcn@latest add "@assistant-ui/elements-typing-indicator"
Usage
import { TypingIndicator } from "@/components/elements/typing-indicator";
<TypingIndicator />Props
variant"bubble" | "bare"bubble wraps the dots in a pill; bare renders only the three dots.
classNamestringExtra classes merged onto the root.
Source
typing-indicator.tsx"use client";
import { cn } from "@/lib/utils";
import { paper } from "./surfaces";
const DOT_DELAYS = ["-0.32s", "-0.16s", "0s"];
export function TypingIndicator({
variant = "bubble",
className,
}: {
variant?: "bubble" | "bare";
className?: string;
}) {
const dots = (
<div
role="status"
aria-label="Assistant is typing"
className={cn("flex gap-1", variant === "bare" && className)}
>
{DOT_DELAYS.map((delay) => (
<span
key={delay}
aria-hidden
className="bg-foreground/40 size-1.5 animate-bounce rounded-full motion-reduce:animate-none"
style={{ animationDelay: delay, animationDuration: "1.1s" }}
/>
))}
</div>
);
if (variant === "bare") {
return dots;
}
return (
<div className={cn(paper, "w-fit rounded-full px-4 py-3.5", className)}>
{dots}
</div>
);
}