Typing Indicator
Three bouncing dots in a bubble, standing in for an incoming message that has not arrived yet — and announcing itself as a live status.
Usage#
import { TypingIndicator } from "neelam-ui";
{isGenerating ? <TypingIndicator label="Assistant is typing…" /> : null}It is styled to match Bubble's incoming shape
directly, because it sits exactly where that bubble will land.
The label is the announcement#
There is no visible text, so label is what assistive tech reads. It defaults
to "Typing…" — pass something specific when the UI knows who:
<TypingIndicator label="Jane is typing…" />Announcing itself#
TypingIndicator carries role="status", so it announces on its own. That is
the opposite of Skeleton, which is explicitly
aria-hidden and leaves announcing to whatever wraps a whole batch of them.
The difference is cardinality: there is normally exactly one typing indicator, for whoever is currently typing, so it is the live status. A screen of skeletons is one loading state rendered many times, and announcing each would be a barrage.
Don't leave it mounted
role="status" is polite, but an indicator that never resolves is an
announcement that never completes. Unmount it as soon as the message arrives
or the request fails.
Keyboard#
| Key | Behaviour |
|---|---|
| Tab | Not focusable. It is a status, not a control. |
Accessibility#
role="status"impliesaria-live="polite", so the label is announced without interrupting whatever the user is doing.- The three dots are
aria-hidden. They are decoration;labelcarries the meaning. - The bounce animation is dropped entirely under
prefers-reduced-motion(WCAG 2.3.3) — the dots simply sit still, and the status still announces. - The staggered
animationDelayis inline style rather than three classes, which keeps the dot count a loop rather than hand-written markup.
API reference#
| Prop | Type | Default |
|---|---|---|
labelAnnounced to assistive tech in place of visible text. Defaults to `"Typing…"` — pass something like `"Jane is typing…"` when the chat UI knows who. | string | Typing… |
Also accepts every native <div> attribute.