# Shimmer Text

> Text with a moving light sweep clipped to the glyphs, with adjustable speed and color.

- Author: Atelier UI
- License: MIT
- Page: https://chromotion.dev/en/components/shimmer-text
- Site: Atelier UI (https://chromotion.dev)

## Install

```bash
npx shadcn@latest add https://chromotion.dev/r/shimmer-text.json
```

Stack: React + TypeScript + Tailwind CSS v4, shadcn/ui conventions. `cn` comes from `@/lib/utils`.

## Dependencies

No extra dependencies.

## Usage

```tsx title="components/shimmer-text-demo.tsx"
import { ShimmerText } from "@/components/shimmer-text"

export default function ShimmerTextDemo() {
  return (
    <div className="flex w-full flex-col items-center gap-5 py-6 text-center">
      <ShimmerText className="text-5xl font-bold tracking-tight">Thinking...</ShimmerText>
      <ShimmerText speed={1.4} spread={22} className="text-xl font-medium">
        Generating your first draft
      </ShimmerText>
      <ShimmerText speed={3.5} shimmerColor="#f97316" className="text-sm font-medium tracking-widest uppercase">
        Coming soon
      </ShimmerText>
    </div>
  )
}
```

## Source

```tsx title="components/shimmer-text.tsx"
import * as React from "react"

import { cn } from "@/lib/utils"

const keyframes = `@keyframes atelier-shimmer{from{background-position:100% 0}to{background-position:-100% 0}}`

export interface ShimmerTextProps extends React.ComponentProps<"span"> {
  /** Seconds per sweep */
  speed?: number
  /** Color of the light sweep. Defaults to a theme-aware highlight */
  shimmerColor?: string
  /** Width of the sweep as a percentage of the text */
  spread?: number
}

// The text color is the base layer of a two-layer background; a narrow
// highlight gradient slides over it and is clipped to the glyphs.
export function ShimmerText({
  speed = 2.4,
  shimmerColor,
  spread = 18,
  className,
  style,
  children,
  ...props
}: ShimmerTextProps) {
  return (
    <span
      className={cn(
        "inline-block bg-clip-text text-transparent [animation-name:atelier-shimmer] [animation-timing-function:linear] [animation-iteration-count:infinite] motion-reduce:animate-none motion-reduce:bg-none motion-reduce:text-muted-foreground",
        "[--shimmer-base:var(--color-muted-foreground)] [--shimmer-hi:var(--color-foreground)]",
        className
      )}
      style={
        {
          ...(shimmerColor ? { "--shimmer-hi": shimmerColor } : null),
          backgroundImage: `linear-gradient(110deg, transparent ${50 - spread}%, var(--shimmer-hi) 50%, transparent ${50 + spread}%), linear-gradient(var(--shimmer-base), var(--shimmer-base))`,
          backgroundSize: "250% 100%, 100% 100%",
          backgroundRepeat: "no-repeat",
          animationDuration: `${speed}s`,
          ...style,
        } as React.CSSProperties
      }
      {...props}
    >
      <style href="atelier-shimmer" precedence="default">
        {keyframes}
      </style>
      {children}
    </span>
  )
}
```
