Skip to content
Component

Text Animate

Staggered text reveals by word, character, or line, with ten animation presets.

Motion gives interfaces a voice.

Installation

terminal
npx shadcn@latest add https://ui.thilina.dev/r/text-animate.json

Usage

app/page.tsx
import { TextAnimate } from "@/components/text-animate";

export default function Page() {
  return (
    <TextAnimate animation="blurInUp" by="word" once>
      Motion gives interfaces a voice.
    </TextAnimate>
  );
}

Split by word for headlines, character for short labels, or line for multi-line copy (separate lines with \n). The animation prop picks one of ten presets: fadeIn, blurIn, blurInUp, blurInDown, slideUp, slideDown, slideLeft, slideRight, scaleUp, and scaleDown. Pass your own variants to replace the preset entirely.

Props

PropTypeDefaultDescription
childrenstring-The text to animate. Plain strings only, since the component splits it into segments.
by"text" | "word" | "character" | "line""word"How the text is split into animated segments.
animationAnimationVariant"fadeIn"One of the ten built-in presets.
asElementType"p"The element rendered around the text.
delaynumber0Seconds to wait before the first segment starts.
durationnumber0.3Total stagger budget, spread across the segments.
startOnViewbooleantrueStart when the element enters the viewport instead of on mount.
oncebooleanfalseAnimate only the first time it enters the viewport.
variantsVariants-Custom motion variants; overrides the preset.
segmentClassNamestring-Class applied to every segment span.

Accessibility

The full text is rendered in a visually hidden span and exposed via aria-label, while the animated segments are aria-hidden, so screen readers announce one coherent sentence instead of dozens of fragments. Under prefers-reduced-motion every duration and stagger collapses to zero, so the text simply appears with nothing moving.

Command Palette

Search for a command to run...