ComponentsTyping
Hover scramble
Scrambles on hover, settles on leave.
Installation
$ npx shadcn@latest add @textlab/hover-scrambleNeeds @textlab in your components.json. Setup takes a minute.
Usage
usage.tsx
import { HoverScramble } from "@/components/textlab/hover-scramble/hover-scramble";
<a href="/work"><HoverScramble text="Selected work" /></a>Variants
sweepallProps
| Prop | Type | Default | Description |
|---|---|---|---|
| text* | string | – | The copy. |
| variant | "sweep" | "all" | "sweep" | sweep re-settles left to right; all snaps back together at the end. |
| charset | string | symbols | Glyphs used while scrambled. |
| duration | number | 0.5 | Seconds each part takes. |
| as | ElementType | "span" | Rendered element. |
| reducedMotion | "user" | "always" | "never" | "user" | user follows the OS setting; always shows the still version. |
| className | string | – | Merged onto the root. |
When to use it
Reach for it
- Navigation links, footers and small buttons on technical brands.
- Any short label where hover feedback should feel playful.
Skip it
- Primary calls to action; the label is briefly unreadable.
- Touch-first interfaces, where hover never happens.
Accessibility and motion
Accessibility
- Keyboard focus triggers it too, through focus capture on the wrapper.
- Screen readers hear the label, never the glyphs.
Motion
- Half a second, under the 300 ms-per-step budget for UI feedback.
- Leaving mid-scramble settles straight back to the word.
Reduced motion. Hover does nothing; the label stays still.
Performance
- Runs only while hovered.
- No layout work; the real label holds the size.