Flip Text
Craft•
A split-flap style text component that animates characters one by one. Supports one-line usage or a composable API with Group, Trigger, and Text—all styled via data-state and className.
How It Works
The component renders each character in a grid of tiles that flip from a random character toward the target. The effect is achieved with CSS animations and a small amount of React state—no motion library. Key behaviors:
-
Replay context —
FlipText.GroupholdsanimationKey,triggerReplay, andhasInitialized. The trigger (hover or click) callstriggerReplay, which bumpsanimationKeyinsidestartTransition, so each tile’s effect re-runs and the flip sequence plays again without blocking the UI. -
Per-tile animation — Each tile runs two animations: an entrance (
flip-text-in: opacity and translateY) and a flip (flip-text-flip: rotateX from -90deg to 0). Keyframes live in the package’sstyle.css. Delays are derived from the tile index (0.15 * index) so tiles animate in a staggered wave. Duration and easing are fixed in the component (e.g. 0.3s ease-out for entrance, 0.25s cubic-bezier for the flip). -
State and styling — Tiles expose
data-state="settled"ordata-state="flipping". You style via Tailwind (e.g.data-[state=settled]:bg-background data-[state=flipping]:bg-tertiary/20) so no inline color or background is required. The root and the flip face both use the same data-state and transition-colors for a consistent look. -
Composable API — Use
<FlipText text="HELLO" />for the default (Group + Trigger + Text), or compose manually:FlipText.GroupwrapsFlipText.TriggerandFlipText.Text. The trigger supportsasChildso you can merge the replay behavior into your own button or link.
Characters outside A–Z and 0–9 render as spaces (fixed-width gaps). The component is keyboard and screen-reader friendly: the default trigger is a button with aria-label set from the text prop.
Was this helpful?