shadcn.io is not affiliated with official shadcn/ui
Text Cursor leaves a trail behind the pointer, like breadcrumbs. As the pointer moves through its area, the next character of its text is dropped every few pixels, turned the way the pointer is going, and drifts up as it fades: sparkles scatter behind a flourish, emoji take turns, and a word spells itself along the path.
Use it for a playful hero, a celebration, a kids' page or a section that should feel alive under the pointer. For a trail of the text itself, use Echo Text; to light up letters near the pointer, Spotlight Text. The trail is a fixed set of characters reused in turn: a handler writes where the next one goes to CSS variables and restarts a CSS keyframe animation the install adds to your stylesheet, with no state, no animation library and no frame loop. With reduced motion each character only fades where it was dropped.
Installation
Usage
import { TextCursor } from "@/components/ui/text-cursor";The trail plays over its own children, inside its box.
<TextCursor className="h-64" text="✨">
<h2>Move the pointer here</h2>
</TextCursor>Demos
Word
A word is dropped a character at a time and in order, so it spells itself along the pointer's path. spacing is how far the pointer moves between one character and the next, 40 pixels by default: about a letter's width reads best for a word. Here the trail is styled through its slot, [&_[data-slot=text-cursor-char]]:text-xl, and takes the area's colour.
Trail
count is the most characters on screen at once, 8 by default, and duration how long each lingers, 1000 ms: more of both makes a longer, denser trail. Several emoji take turns. orient={false} keeps every character upright, whichever way the pointer moves.
Accessibility
The trail is decoration: hidden from screen readers and from the pointer, so it's never read out and never blocks a click on the content beneath, and clipped to the area. The content is your children, read and used as usual. On a touch screen a tap drops one character where it lands, and dragging a finger scrolls the page as usual, with no trail. With reduced motion each character appears and fades where it was dropped, without drifting.
FAQ
Does it re-render as the pointer moves?
No. The trail is a fixed set of characters rendered once. As the pointer passes each spacing, a handler moves the next one to the pointer through CSS variables and restarts its animation; nothing else runs, and nothing at all once the pointer stops.
What does a word do?
Its characters are dropped in order, one every spacing pixels, each turned along the path, so moving the pointer writes the word. End it with a space to separate one pass from the next.
How do I size or colour the trail?
The characters take the area's text colour, and each is a data-slot="text-cursor-char" you can style from outside, such as [&_[data-slot=text-cursor-char]]:text-4xl on the component.
Can the trail cover the whole page?
The trail stays inside the component's box, clipped to it. For the whole page, wrap the page's content in it, so its box is the page's.
API Reference
TextCursor
<div> data-slot="text-cursor"
textstring
What trails the pointer: an emoji, a symbol or a word, dropped a character at a time and in order, so a word spells itself along the path.
children?ReactNode
What the trail plays over: the area's own content.
count?number
The most trail characters on screen at once.
- Default
8
duration?number
How long a trail character lingers, drifting up as it fades, in milliseconds.
- Default
1000
orient?boolean
Whether each character turns to the way the pointer moves (never upside down). @default true.
- Default
true
spacing?number
How far the pointer moves between one trail character and the next, in pixels. @default 40.
- Default
40
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
--text-cursor-durationstring
A trail character's drift and fade (1000ms).
Related
- Pro
Echo Text
DecorativeFainter copies trailing the text
- Pro
Scrambled Text
DecodeA trail of churning glyphs
- Pro
Magnet Text
InteractiveLetters pulled toward the pointer
- Pro
Variable Proximity
InteractiveLetters thicken near the pointer
- Pro
Erase Text
InteractiveA fading trail through the letters
- Pro
Every detail deserves the spotlightEvery detail deserves the spotlight
Spotlight Text
InteractiveA beam that follows the pointer