Shimmer Text
betaAnimated gradient sweep across text — the canonical “Thinking…” / “Searching…” label for in-progress AI work.
Thinking label
minimal
Thinking…
Tuned sweep
Every prop: element, speed, band width, and toggling `active` when work completes.
full
Searching 24 sources…
Agent step with status region
A tool-call style row announcing progress politely to screen readers.
composition
Reading package.json…
Installation
npx shadcn@latest add https://kuro.abstergo.fyi/r/shimmer-text.jsonCopies the source into components/kura/shimmer-text with its dependencies (kura-theme, utils). Tokens come from the kura-theme item.
When to use it
Use it for
- Show that a model or agent is working: “Thinking…”, “Searching the web…”, “Reading 12 files…”.
- Label the current step of a running tool call or reasoning trace.
- A lightweight inline loading label where a spinner would be too mechanical.
Reach for something else when
- Long paragraphs or body text — the sweep hurts legibility beyond a short phrase.
- Determinate progress (uploads, token budgets) — use a progress bar or context-meter.
- Streaming the model's answer itself — use streaming-text.
- A standalone animated dot/orb indicator — use thinking-indicator or agent-orb.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| children* | React.ReactNode | — | The text to shimmer. Plain text reads best; inline elements are allowed. |
| active | boolean | true | Animate the sweep. Set false when the work finishes to settle into muted text. |
| duration | number | 2 | Seconds per sweep. Keep between 1.5 (urgent) and 3 (calm). |
| spread | number | 30 | Width of the bright band as a % of the text width (clamped 5–80). |
| as | "span" | "p" | "div" | "strong" | "em" | "span" | Element to render. |
All native attributes of the root element, className and ref pass through.
Anatomy
- ShimmerTextA single inline element; `data-active` reflects the `active` prop.
data-slot="shimmer-text"
Accessibility
- The text stays real text: screen readers read it normally; the animation is purely visual.
- Not a live region. Wrap the label in an element with role="status" (or aria-live="polite") if the change of state should be announced.
- Colors come from fg/fg-subtle tokens so contrast holds in light and dark mode.
- Reduced motion: The sweep is removed; the text renders as static muted text.
Notes for agents
- Server-component safe: no hooks, pure CSS animation. No "use client" needed to render it.
- Flip `active` to false instead of unmounting when work completes, so layout does not jump.
- Keep the label under ~6 words and end with an ellipsis (…) while active.