Shimmer
The Shimmer component animates a sweep of light across text, most often to signal that content is still generating in AI and chat interfaces. It wraps a single string of text and renders it as any element you choose.
Variations
With different duration
Control the animation speed with the duration prop (in seconds).
With different spread
The spread prop controls the width of the shimmer highlight (multiplied by the text length). Higher values create a wider band of light.
With different colors
Use the color prop to change the shimmer text color. It uses the same color tokens as the Text component.
Custom element type
Use the as prop to render the shimmer as a different HTML element.
Installation
import { Shimmer } from '@harnessio/ui/components'
// Basic usage<Shimmer>Generating response...</Shimmer>
// With custom color<Shimmer color="foreground-1"> Processing your request...</Shimmer>
// With custom duration and spread<Shimmer duration={3} spread={3} color="brand"> Loading...</Shimmer>
// As a different element<Shimmer as="h2" variant="heading-base"> Loading title...</Shimmer>Anatomy
Shimmer renders a single line of text (passed as children) inside a <p> by default, with an infinitely-repeating gradient sweep. It takes the same typographic variant and color tokens as Text, so it slots in wherever a piece of text would go.
<Shimmer>Generating response...</Shimmer>childrenmust be a plain string — the component measures its length to size the shimmer band, so it can’t wrap arbitrary nodes.asswaps the rendered element (pby default) — usespaninline, or a heading element for a loading title.variantandcolormatch theTextcomponent’s typography and color tokens, so the shimmering text lines up with the real text it stands in for.
Best practices
Do
- Reach for
Shimmeron short, transient labels — “Thinking…”, “Generating response…” — while a model is working. - Match the
variantandcolorto the text that will replace it, so the swap-in doesn’t shift the layout. - Swap the shimmer for the real content as soon as it’s ready; it’s a waiting state, not a decoration.
Don’t
- Don’t use it for long passages or multi-line blocks — it’s tuned for a single short string.
- Don’t leave it running indefinitely; if a request stalls, show an error or retry instead of an endless shimmer.
Content
- Keep the text short and in the present tense while active (“Analyzing…”, “Loading…”).
- Prefer a specific label (“Reviewing your code…”) over a generic “Loading…” when you know what’s happening.
Accessibility
Labeling
Shimmerrenders ordinary text, so its content is read normally by screen readers. If it marks a region that’s actively updating, consider placing it inside anaria-liveregion so the eventual result is announced.
Focus & states
- The effect is purely visual (an animated background sweep) and adds no roles or interactivity. The animation loops continuously while mounted; unmount it once the real content arrives.
Properties
Prop | Required | Default | Type |
|---|---|---|---|
| children | true | string | |
| as | false | 'p' | ElementType |
| variant | false | 'body-normal' | 'heading-hero' | 'heading-section' | 'heading-default' | 'heading-subsection' | 'heading-base' | 'heading-small' | 'body-normal' | 'body-single-line-normal' | 'body-strong' | 'body-single-line-strong' | 'body-code' | 'caption-normal' | 'caption-light' | 'caption-strong' | 'caption-code' | 'caption-single-line-normal' |
| color | false | 'foreground-2' | 'foreground-1' | 'foreground-2' | 'foreground-3' | 'foreground-4' | 'disabled' | 'success' | 'warning' | 'danger' | 'brand' | 'merged' |
| duration | false | 2 | number |
| spread | false | 2 | number |
| className | false | string |