Elements

Components / Base

Shimmer

Animated gradient shimmer that sweeps across text using the brand gradient (forest → lime → forest). Painted directly on the letterforms viabackground-clip: text - ideal for in-progress or streaming states.

Installation

bash
npx shadcn add https://raw.githubusercontent.com/levi-putna/elements/main/registry/shimmer/registry.json

Usage

tsx
import { Shimmer } from "@/components/ui/shimmer"

export function Loading() {
  return (
    <p className="text-2xl font-bold">
      <Shimmer>Generating your report…</Shimmer>
    </p>
  )
}

The sweep depends on a text-shimmer keyframe. Add it to your globals.css:

css
/* globals.css: required for the sweep */
@keyframes text-shimmer {
  0%   { background-position: 200% center; }
  100% { background-position: 0% center; }
}

Examples

Live preview

A streaming-style status line.

Preview
Generating your report…

Loading status

Paragraph-sized text with a leading spinner and trailing ellipsis: useful for inline loading or streaming states.

Preview

Generating your report

tsx
import { Shimmer } from "@/components/ui/shimmer"
import { Spinner } from "@/components/ui/spinner"

export function LoadingStatus() {
  return (
    <p className="flex items-center gap-2 text-base text-foreground">
      <Spinner className="size-3.5 text-forest" />
      <Shimmer className="text-base font-normal">Generating your report</Shimmer>
      <span aria-hidden="true">...</span>
    </p>
  )
}

Tuning the sweep

Adjust duration andspread, or render a different element withas.

tsx
{/* duration controls the sweep speed (seconds) */}
<Shimmer duration={3}>Slower sweep</Shimmer>

{/* spread widens or narrows the bright band */}
<Shimmer spread={4}>Wider highlight</Shimmer>

{/* as renders a different element: defaults to span */}
<Shimmer as="h2" className="text-3xl font-bold">Heading shimmer</Shimmer>

Props

PropTypeDefaultDescription
asElementType"span"HTML element (or component) to render. Defaults to span so it can sit inline within text.
durationnumber2Animation duration in seconds. Higher is slower.
spreadnumber2Spread multiplier: higher values widen the bright band that sweeps across the letterforms.
classNamestring-Additional classes. inline-block is always applied so background-clip works.
childrenReactNode-Text content the shimmer is painted on.