Shimmer
Animated highlight sweeping across content.
A highlight that sweeps through text and content, for loading, thinking and streaming states.
The content is used as a mask and a gradient band is swept behind it on the UI thread, so the highlight is clipped to the glyph shapes — the letters catch the light rather than sitting under a passing overlay.
For a placeholder where there is no content yet, use Skeleton.
Installation
Shimmer ships with the library — no separate install.
import { Shimmer, Skeleton } from 'panelui-native';Or copy the source into your project, to own and edit it:
npx panelui-cli@latest add shimmerUsage
<Shimmer>Thinking…</Shimmer>
<Shimmer duration={1400} textClassName="text-lg font-medium">
Generating response…
</Shimmer>
// Mask arbitrary content instead of a string.
<Shimmer as="view" className="w-full gap-2">
<Skeleton className="h-4 w-3/4" />
<Skeleton className="h-4 w-full" />
</Shimmer>Examples
A thinking indicator
The default. The sweep is clipped to the glyphs, so the letters catch the light instead of sitting under a passing band.
<Shimmer>Thinking…</Shimmer>
<Shimmer duration={1400} textClassName="text-lg font-medium">
Generating response…
</Shimmer>Masking a subtree
as="view" masks the sweep to whatever you pass instead of to a string.
<Shimmer as="view" className="w-full gap-2">
<Skeleton className="h-4 w-3/4" />
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-1/2" />
</Shimmer>Tuning the sweep
{/* Reverses on each pass instead of restarting from the left. */}
<Shimmer mode="ping-pong" duration={1600}>Ping-pong</Shimmer>
{/* Right to left. */}
<Shimmer reverse>Reversed</Shimmer>
{/* A wider, slower band. */}
<Shimmer spread={4} duration={2600}>Slow and broad</Shimmer>
{/* One pass, then stop. */}
<Shimmer once>Sweeps once</Shimmer>Custom colours
Both default to theme tokens, so you only need these on a surface the tokens do not suit.
<Shimmer baseColor="#3f3f46" shimmerColor="#fafafa">
Neutral on dark
</Shimmer>Turning it off
Renders the content statically in baseColor. Useful for stopping the sweep the moment a stream finishes, without swapping components.
<Shimmer enabled={isStreaming}>{status}</Shimmer>API Reference
Shimmer
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | |
as | 'text' | 'view' | 'text' | text renders children as a single styled string and masks the sweep to the glyphs. view masks the sweep to whatever subtree you pass. |
duration | number | 2000 | Milliseconds for one sweep. |
spread | number | 2 | Width of the highlight band, as a multiple of the content width. |
baseColor | string | — | Colour of the content at rest. Defaults to the theme's muted foreground. |
shimmerColor | string | — | Colour at the centre of the sweep. Defaults to the theme's foreground. |
mode | 'loop' | 'ping-pong' | 'loop' | loop restarts from the left; ping-pong reverses on each pass. |
once | boolean | false | Sweep once instead of repeating. |
reverse | boolean | false | Sweep right-to-left. |
enabled | boolean | true | Set false to render the content statically without animating. |
textClassName | string | — | Extra classes for the text when as="text". |
textStyle | StyleProp<TextStyle> | — | Extra styles for the text when as="text". |
color | string | — | Deprecated. Use shimmerColor. |
intensity | number | — | Peak opacity of the highlight. Deprecated. Set shimmerColor to a colour with the alpha you want. |
Every part also accepts the underlying React Native props (ViewProps or TextProps) and a className for Tailwind utilities.
Notes
The sweep runs entirely on the UI thread and never re-renders React while animating.
It stops when the OS reduce-motion setting is on, and when enabled is false — in both cases the content renders statically in baseColor.
baseColor and shimmerColor default to the theme's muted-foreground and foreground tokens, so the effect reads correctly on any surface without configuration. color and intensity still work but are deprecated in favour of the two colour props.
Public exports
Values: Shimmer
Types: ShimmerProps