ComponentsReveal
Split text
Stagger anything by chars, words or lines.
Installation
$ npx shadcn@latest add @textlab/split-textNeeds @textlab in your components.json. Setup takes a minute.
Usage
usage.tsx
import { SplitText } from "@/components/textlab/split-text/split-text";
<SplitText variant="chars" order="center" preset="zoom" text="From the middle out" />Variants
wordscharslinesProps
| Prop | Type | Default | Description |
|---|---|---|---|
| text* | string | – | The copy. |
| variant | "chars" | "words" | "lines" | "words" | How the text is split. Lines are measured from layout and re-measured on resize. |
| preset | "fade-up" | "fade-down" | "zoom" | "blur" | "flip" | "fade-up" | A named starting pose. |
| from | TargetAndTransition | (index, total) => TargetAndTransition | – | Custom starting pose per part. Overrides preset. |
| order | "start" | "end" | "center" | "edges" | "start" | Which part moves first. |
| clip | boolean | false | Clip each part so it appears out of nothing. |
| as | ElementType | "span" | Rendered element. |
| trigger | "mount" | "inView" | "hover" | "manual" | "inView" | What starts the animation. manual follows `active`. |
| active | boolean | false | Drives trigger="manual". |
| once | boolean | true | In view: play once instead of on every entry. |
| delay | number | 0 | Seconds before the first part moves. |
| stagger | number | – | Seconds between parts. |
| duration | number | 0.8 | Seconds each part takes. |
| ease | EaseName | [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. |
| className | string | – | Merged onto the root. |
| onComplete | () => void | – | Called when a one-shot animation finishes. |
When to use it
Reach for it
- Custom entrances the other reveals do not cover.
- Choreography where order matters: center out, edges in.
Skip it
- When a named reveal already fits; they carry better defaults.
- Long body copy split by chars.
Accessibility and motion
Accessibility
- One visually hidden copy for screen readers; every part is aria-hidden.
- Splits by grapheme, so emoji and combined letters stay whole.
Motion
- Default stagger: 20 ms per char, 60 ms per word, 100 ms per line.
- Opacity leads, filter follows, transform settles last.
Reduced motion. Shows plain text with no splitting.
Performance
- Up to ~200 parts per instance.
- Line mode measures once per frame on resize.