Blur Text
motiq/blur-textFreeComponent
Reveals text segment-by-segment with a de-blur and drift. Reduced-motion safe.
Live preview
live · rendered by the registry
Rendered by motiq on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://www.motiq.dev/r/blur-text.jsonSource
1"use client";23import * as React from "react";4import { motion, useReducedMotion, type Transition } from "motion/react";56import { cn } from "@/lib/utils";78type AnimateBy = "words" | "chars";9type Direction = "top" | "bottom";1011export interface BlurTextProps {12 /** The text to reveal. */13 text: string;14 className?: string;15 /** Milliseconds of stagger between each segment. */16 delay?: number;17 /** Reveal word-by-word or character-by-character. */18 animateBy?: AnimateBy;19 /** Which side each segment drifts in from. */20 direction?: Direction;21 /** Animate only the first time it enters the viewport. */22 once?: boolean;23 /** Element tag to render (e.g. "h1", "p"). */24 as?: React.ElementType;25}2627const EASE: Transition["ease"] = [0.2, 0, 0, 1];2829/**30 * BlurText — reveals text segment-by-segment with a de-blur + drift.31 *32 * Accessibility: the full string is exposed once via `aria-label`; the animated33 * segments are `aria-hidden`. Under `prefers-reduced-motion` the text renders in34 * its final state with no animation. Clean-room original.35 */36export function BlurText({37 text,38 className,39 delay = 60,40 animateBy = "words",41 direction = "top",42 once = true,43 as: Tag = "span",44}: BlurTextProps) {45 const reduce = useReducedMotion();46 const segments = React.useMemo(47 () => (animateBy === "words" ? text.split(" ") : Array.from(text)),48 [text, animateBy],49 );50 const y = direction === "top" ? -14 : 14;5152 return (53 <Tag className={cn("inline-flex flex-wrap", className)} aria-label={text}>54 {segments.map((seg, i) => (55 <motion.span56 key={`${seg}-${i}`}57 aria-hidden="true"58 className="inline-block whitespace-pre [will-change:transform,filter]"59 initial={reduce ? false : { opacity: 0, y, filter: "blur(8px)" }}60 whileInView={reduce ? undefined : { opacity: 1, y: 0, filter: "blur(0px)" }}61 viewport={{ once, margin: "-10% 0px" }}62 transition={{ duration: 0.5, ease: EASE, delay: (i * delay) / 1000 }}63 >64 {seg}65 {animateBy === "words" && i < segments.length - 1 ? " " : null}66 </motion.span>67 ))}68 </Tag>69 );70}7172export default BlurText;
What it pulls in
npm packages
Other registry items
Files it writes
More from motiq
All 100 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Activity Streamactivity-stream | motiq | Components | Free | 1 dep | |
| Adaptive Safe-Zone Gridadaptive-safe-zone-grid | motiq | Components | Free | no deps | |
| Agent Run Timelineagent-run-timeline | motiq | Components | Free | 1 dep | |
| AI Response Streamai-response-stream | motiq | Components | Free | 1 dep | |
| Animated Accordionanimated-accordion | motiq | Components | Free | 2 deps | |
| Animated Buttonanimated-button | motiq | Components | Free | 1 dep | |
| Animated Dialoganimated-dialog | motiq | Components | Free | 2 deps | |
| Animated Gridanimated-grid | motiq | Components | Free | 2 deps |
