ComponentsTyping
Typewriter
Types, deletes and retypes with a caret.
Installation
$ npx shadcn@latest add @textlab/typewriterNeeds @textlab in your components.json. Setup takes a minute.
Usage
usage.tsx
import { Typewriter } from "@/components/textlab/typewriter/typewriter";
<Typewriter words={["for designers", "for engineers", "for everyone"]} reserve />Variants
barblockunderscoreProps
| Prop | Type | Default | Description |
|---|---|---|---|
| words* | string[] | – | Phrases to type in turn. |
| variant | "bar" | "block" | "underscore" | "bar" | Caret shape. |
| typeSpeed | number | 70 | Milliseconds per typed letter, before jitter. |
| deleteSpeed | number | 38 | Milliseconds per deleted letter. |
| pause | number | 1600 | Milliseconds a finished phrase is held. |
| loop | boolean | true | Keep cycling through the phrases. |
| humanize | boolean | true | Small, repeatable variations in key timing. |
| reserve | boolean | false | Reserve the longest phrase's width so nothing around it moves. |
| label | string | – | What screen readers hear. Defaults to every phrase. |
| as | ElementType | "span" | Rendered element. |
| trigger | "mount" | "inView" | "manual" | "inView" | What starts the animation. manual follows `active`. |
| delay | number | 0 | Seconds before the first part moves. |
| 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
- Rotating endings on hero lines.
- Terminal and chat-style interfaces.
Skip it
- Critical information that must be readable at once.
- More than a handful of phrases.
Accessibility and motion
Accessibility
- Screen readers hear every phrase once from a hidden label, not each keystroke.
- Use reserve in centered layouts so surrounding text does not shift.
Motion
- The caret is solid while typing or deleting and blinks only at rest.
- Spaces take a little longer, like a real typist.
Reduced motion. Shows a phrase in full with no typing and no caret.
Performance
- One timer at a time; no animation frames.
- The caret blink is a CSS keyframe.