Shimmer
A travelling highlight painted into text, or a surface band over children the runtime cannot recolour
Generating a reply…
The assistant is reading the conversation.
Thinking…
Thinking…
Usage
import { Shimmer } from "@gpuixui/components/shimmer";
// A plain string is inked one code point at a time from the travelling profile.
<Shimmer label="Generating a reply" durationMs={2000}>
Generating a reply…
</Shimmer>;
// A finished surface: the text rests and no profile runs.
<Shimmer active={false}>Done</Shimmer>;
// Composed children cannot be recoloured, so they keep the surface band.
<Shimmer label="Reading the conversation">
<Card>
<Text role="body">The assistant is reading the conversation.</Text>
</Card>
</Shimmer>;A string child is a text run: every code point is its own text host and takes the profile's ink at its place in the line. Any other child keeps the surface band — a row of thin two-stop ramps over the content — because the runtime cannot recolour a tree it did not build.
Two drawings, honestly
The browser can put a gradient inside the glyphs with background-clip: text.
The native runtime cannot: it has no mask and no background-clip, and a <text>
host paints one color. So the native component does the strongest thing it can
and says what it is:
- A string child is split into words and code points. Each code point takes
one colour sampled from the same triangular profile the band uses, blending
from the theme's
mutedForegroundtoward the chosen accent. The sheen is discrete at glyph resolution, not a continuous fill. - Any other child keeps the band:
SHIMMER_STEPS(16) strips, each a two-stop ramp between neighbouring samples of that profile, stepping once perdurationMs / SHIMMER_STEPS(125 ms at the default).
The two paths are not the same drawing, and neither is presented as the other. The browser preview puts the gradient in the text; the native string path is the closest the runtime gets to it.
API
| Prop | Type | Default | Consequence |
|---|---|---|---|
children | ReactNode | none | a string is inked per code point; any other child keeps the surface band |
active | boolean | true | whether the profile runs; false rests the text and paints no band |
durationMs | number | 2000 | one complete sweep; an unusable value falls back to two seconds |
accent | "foreground" | "primary" | "muted" | "foreground" | the role the highlight paints; a text run blends toward it from the muted role, a band paints it at a low alpha |
role | text role | "body" | the typographic role a text run paints |
label | string | none | an accessible name; when set, the surface is a status node, and a blank name is decoration |
reducedMotion | boolean | the motion provider | rests the text, paints no band and schedules no interval |
className | string | — | joined after the surface recipe, so it wins conflicts |
style | StyleState<ShimmerState> | — | a style, or a function of the frame's peak, active and reducedMotion |
testId | string | — | stable locator; a text run is testId-ink, a band is testId-overlay |
Edit this page on GitHubpackages/components/docs/shimmer.mdx