Skip to content
Textlab
1
Browse

ComponentsReveal

Word reveal

Words rise out of a clip.

Ship the story, not the slides

Installation

$ npx shadcn@latest add @textlab/word-reveal

Needs @textlab in your components.json. Setup takes a minute.

Usage

usage.tsx
import { WordReveal } from "@/components/textlab/word-reveal/word-reveal";

<WordReveal as="h1" text="Ship the story, not the slides" />

Variants

risefallscale

Props

PropTypeDefaultDescription
text*string–The copy.
variant"rise" | "fall" | "scale""rise"rise comes up from below the line, fall drops from above, scale grows from the baseline.
asElementType"span"Rendered element.
trigger"mount" | "inView" | "hover" | "manual""inView"What starts the animation. manual follows `active`.
activebooleanfalseDrives trigger="manual".
oncebooleantrueIn view: play once instead of on every entry.
delaynumber0Seconds before the first part moves.
staggernumber0.06Seconds between parts.
durationnumber0.8Seconds each part takes.
easeEaseName | [number, number, number, number]"enter"Easing token or cubic bezier.
reducedMotion"user" | "always" | "never""user"user follows the OS setting; always shows the still version.
classNamestring–Merged onto the root.
onComplete() => void–Called when a one-shot animation finishes.

When to use it

Reach for it

  • Editorial headlines where each word should land with weight.
  • Hero lines on load with trigger="mount".

Skip it

  • Long paragraphs; the stagger gets slow past ~20 words.
  • Text inside buttons or form labels.

Accessibility and motion

Accessibility

  • Screen readers get the full sentence once; the clipped words are aria-hidden.
  • Pass as="h1" or as="h2" to keep the outline.

Motion

  • Each word travels its own height, so the motion scales with font size.
  • Words start 60 ms apart and settle with the enter ease.
Reduced motion. Renders the sentence in place with no clip or movement.

Performance

  • Transform and opacity only.
  • One motion span per word.