LLM index: /llms.txt

Text Shimmer

An animated shimmer effect for loading and "in progress" feedback. TextShimmer renders a moving highlight across text and exposes controls for speed, spread, direction, contrast, and pause between passes.

Thinking through your request...
"use client";

import { TextShimmer } from "@/components/nexus-ui/text-shimmer";

const TextShimmerDefault = () => {
  return (
    <div className="flex min-h-24 w-full items-center justify-center">
      <TextShimmer className="text-sm leading-6">
        Thinking through your request...
      </TextShimmer>
    </div>
  );
};

export default TextShimmerDefault;

Installation

npx shadcn@latest add @nexus-ui/text-shimmer
pnpm dlx shadcn@latest add @nexus-ui/text-shimmer
yarn dlx shadcn@latest add @nexus-ui/text-shimmer
bunx shadcn@latest add @nexus-ui/text-shimmer

Copy and paste the following code into your project.

components/nexus-ui/text-shimmer.tsx
"use client";

import * as React from "react";

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

export type TextShimmerProps = Omit<
  React.HTMLAttributes<HTMLElement>,
  "color"
> & {
  as?: React.ElementType;
  /**
   * Duration in seconds.
   * @default 4
   */
  duration?: number;
  /**
   * Spread around center in percent points.
   * @default 20
   */
  spread?: number;
  /**
   * Beam angle in degrees.
   * @default 0
   */
  angle?: number;
  /**
   * Override highlight color.
   */
  color?: string;
  /**
   * Invert shimmer contrast.
   * @default false
   */
  invert?: boolean;
  /**
   * Delay before the next shimmer pass in seconds.
   * @default 0
   */
  repeatDelay?: number;
};

function TextShimmer({
  as: Comp = "span",
  className,
  style,
  duration = 4,
  repeatDelay = 0,
  spread = 20,
  angle = 0,
  color,
  invert = false,
  children,
  ...props
}: TextShimmerProps) {
  const id = React.useId();
  const boundedSpread = Math.min(Math.max(spread, 5), 45);
  const activeDuration = Math.max(duration, 0);
  const pauseDuration = Math.max(repeatDelay, 0);
  const totalDuration = Math.max(activeDuration + pauseDuration, 0.001);
  const movePercent = (activeDuration / totalDuration) * 100;
  const keyframeName = React.useMemo(
    () => `nx-text-shimmer-${id.replace(/[^a-zA-Z0-9_-]/g, "")}`,
    [id],
  );
  const start = 50 - boundedSpread;
  const end = 50 + boundedSpread;
  const edge = "currentColor";
  const beam = invert
    ? (color ??
      "oklch(from currentColor min(calc(l - 0.4), 0.2) c h / calc(alpha + 0.4))")
    : (color ??
      "oklch(from currentColor max(0.8, calc(l + 0.4)) c h / calc(alpha + 0.35))");
  const keyframes = `@keyframes ${keyframeName} {
    0% { background-position: 200% 50%; }
    ${movePercent}% { background-position: -200% 50%; }
    100% { background-position: -200% 50%; }
  }`;

  return (
    <>
      <style>{keyframes}</style>
      <Comp
        className={cn("bg-size-[200%_auto] bg-clip-text", className)}
        style={{
          backgroundImage: `linear-gradient(${90 + angle}deg, ${edge} ${start}%, ${beam} 50%, ${edge} ${end}%)`,
          animation: `${keyframeName} ${totalDuration}s linear infinite`,
          WebkitTextFillColor: "transparent",
          ...style,
        }}
        {...props}
      >
        {children}
      </Comp>
    </>
  );
}

export { TextShimmer };

Update import paths to match your project setup.

Usage

import { TextShimmer } from "@/components/nexus-ui/text-shimmer";
<TextShimmer>
  Running tool calls
</TextShimmer>

Examples

Angled Shimmer

Tune beam geometry with spread and angle:

Re-ranking search results
"use client";

import { TextShimmer } from "@/components/nexus-ui/text-shimmer";

const TextShimmerAngled = () => {
  return (
    <div className="flex min-h-24 w-full items-center justify-center">
      <TextShimmer className="text-sm leading-6" spread={30} angle={18}>
        Re-ranking search results
      </TextShimmer>
    </div>
  );
};

export default TextShimmerAngled;

Inverted Contrast

Use invert for lower-luminance emphasis (often better on lighter text):

Processing tool output...
"use client";

import { TextShimmer } from "@/components/nexus-ui/text-shimmer";

const TextShimmerInverted = () => {
  return (
    <div className="flex min-h-24 w-full items-center justify-center">
      <TextShimmer className="text-sm leading-6" invert>
        Processing tool output...
      </TextShimmer>
    </div>
  );
};

export default TextShimmerInverted;

As Custom Element

Render another element type with as:

Compiling component registry

"use client";

import { TextShimmer } from "@/components/nexus-ui/text-shimmer";

const TextShimmerAsParagraph = () => {
  return (
    <div className="flex min-h-24 w-full items-center justify-center px-6">
      <TextShimmer
        as="p"
        className="max-w-md text-center text-sm leading-6"
      >
        Compiling component registry
      </TextShimmer>
    </div>
  );
};

export default TextShimmerAsParagraph;

Custom Highlight Color

Use color to override the highlight beam for accent-driven states:

Syncing vector index
"use client";

import { TextShimmer } from "@/components/nexus-ui/text-shimmer";

const TextShimmerCustomColor = () => {
  return (
    <div className="flex min-h-24 w-full items-center justify-center">
      <TextShimmer
        className="text-sm leading-6"
        color="oklch(0.78 0.12 255)"
      >
        Syncing vector index
      </TextShimmer>
    </div>
  );
};

export default TextShimmerCustomColor;

Slow Sweep

Increase duration for a calmer motion profile:

Analyzing conversation context
"use client";

import { TextShimmer } from "@/components/nexus-ui/text-shimmer";

const TextShimmerSlowSweep = () => {
  return (
    <div className="flex min-h-24 w-full items-center justify-center">
      <TextShimmer className="text-sm leading-6" duration={5.5} spread={16}>
        Analyzing conversation context
      </TextShimmer>
    </div>
  );
};

export default TextShimmerSlowSweep;

Tight Beam

Lower spread for a narrower, sharper highlight pass:

Running tool calls
"use client";

import { TextShimmer } from "@/components/nexus-ui/text-shimmer";

const TextShimmerTightBeam = () => {
  return (
    <div className="flex min-h-24 w-full items-center justify-center">
      <TextShimmer className="text-sm leading-6" spread={8} duration={1.6}>
        Running tool calls
      </TextShimmer>
    </div>
  );
};

export default TextShimmerTightBeam;

API Reference

TextShimmer

Animated text wrapper component. Uses a generated keyframe name per instance to avoid collisions and applies shimmer via a gradient background clipped to text.

Prop

Type