Typing Animation
A zero-dependency typing effect for text elements with a customizable blinking cursor, delays, and duration.
|
Installation
1. Copy the component into your project:
tsx
"use client";
import React, { useState, useEffect } from "react";
export interface TypingAnimationProps extends React.HTMLAttributes<HTMLSpanElement> {
text: string;
duration?: number;
delay?: number;
cursor?: boolean;
}
export const TypingAnimation = ({
text,
duration = 50,
delay = 0,
cursor = true,
className = "",
...props
}: TypingAnimationProps) => {
const [displayedText, setDisplayedText] = useState("");
const [isStarted, setIsStarted] = useState(false);
useEffect(() => {
let timeout: NodeJS.Timeout;
if (delay > 0) {
timeout = setTimeout(() => setIsStarted(true), delay);
} else {
setIsStarted(true);
}
return () => clearTimeout(timeout);
}, [delay]);
useEffect(() => {
if (!isStarted) return;
let currentIndex = 0;
const intervalId = setInterval(() => {
setDisplayedText(text.slice(0, currentIndex + 1));
currentIndex++;
if (currentIndex === text.length) {
clearInterval(intervalId);
}
}, duration);
return () => clearInterval(intervalId);
}, [text, duration, isStarted]);
return (
<span className={`bare-typing-animation ${className}`} {...props}>
{displayedText}
{cursor && (
<span className="bare-typing-cursor" aria-hidden="true">
|
</span>
)}
</span>
);
};
Usage
tsx
import { TypingAnimation } from "@/components/ui/typing-animation";
export default function MyComponent() {
return (
<TypingAnimation
text="Hello, Bare UI!"
duration={100}
delay={500}
cursor={true}
/>
);
}