Text loop
FreeOne word in a sentence that cycles through a few options. The widest word reserves the space, it pauses on hover, focus, off screen and in a hidden tab, and a pause button stops it.
pnpm dlx shadcn@latest add https://caliperui.site/r/text-loop.jsonClose the books faster, with fewer errors, from anywhere
Ask about revenue, churn, refunds, pipeline in plain words.
When to use #
Use it for
- A marketing headline with three or four audiences or outcomes.
- An empty state that hints at what you can ask.
Skip it when
- Information people need to read; every option must also make sense alone.
- Product UI and controls; keep labels still.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/text-loop.json
Adds its 2 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
import { TextLoop } from "@/components/ui/text-loop" export function TextLoopDemo() { return ( <div className="grid gap-6"> <h2 className="text-3xl font-medium tracking-[-0.02em]"> Close the books <TextLoop words={["faster", "with fewer errors", "from anywhere"]} reserve={false} className="text-muted-foreground" /> </h2> <p className="text-sm text-muted-foreground"> Ask about <TextLoop words={["revenue", "churn", "refunds", "pipeline"]} control={false} className="font-medium text-foreground" /> in plain words. </p> </div> ); }
API reference #
TextLoop
component
Accessibility #
It is built on native elements and keeps aria-hidden, aria-label and aria-pressed in step with state.
No custom key handling; Tab and the native activation keys do the work.
Motion #
It checks prefers-reduced-motion itself and settles immediately instead of travelling. Every state is still reachable.