Text Shimmer

Animated

A shimmer for pending states where a spinner would be too loud.

View Source

#Installation

npx @dinachi/cli@latest add text-shimmer

#Usage

tsx
import { TextShimmer } from "@/components/ui/text-shimmer"
tsx
{isGenerating && <TextShimmer>Thinking…</TextShimmer>}

#Examples

#Variants

VariantUse it when
sweepLabel-sized text, where a band has room to read.
pulseDense or small text, where a band is too subtle. Also the cheaper of the two: it animates opacity and nothing else.

Both are built from currentColor, so they inherit the surrounding text colour.

#When to use it

It signals that something is in flight, and it loops for as long as it is mounted. Mount it when the work starts and unmount it when the work lands.

Use it forNot for
A label reporting work in flight: Thinking…, Generating, Uploading.Settled text. A loop running over a finished value is noise.
Label-sized text.A paragraph. The shimmer repaints its own box on every frame, so the cost scales with the area.

#Accessibility

  • The span carries role="status", because it reports a pending state.
  • Reduced motion stops the loop. A continuous ambient animation has no gentler version worth keeping, but the dim colour stays, so the label still reads as unsettled.

#API Reference

PropTypeDefaultDescription
variant"sweep" | "pulse""sweep"A highlight band travelling across the text, or the whole label breathing between dim and lit
durationnumber1.6 / 1.8Seconds for one cycle. Defaults per variant
dimnumber0.7How dim the un-lit text is, 0–1. This is a label the user is waiting on, not a placeholder, so it has to stay readable