personal_website/src/components/TypingText.tsx

51 lines
1.2 KiB
TypeScript

import { useState, useEffect } from 'react';
import { useSettings } from '@/contexts/SettingsContext';
interface TypingTextProps {
text: string;
className?: string;
speed?: number;
delay?: number;
onComplete?: () => void;
}
const TypingText = ({ text, className = '', speed = 50, delay = 0, onComplete }: TypingTextProps) => {
const [displayedText, setDisplayedText] = useState('');
const [isTyping, setIsTyping] = useState(false);
const { playSound } = useSettings();
useEffect(() => {
const startTimeout = setTimeout(() => {
setIsTyping(true);
}, delay);
return () => clearTimeout(startTimeout);
}, [delay]);
useEffect(() => {
if (!isTyping) return;
if (displayedText.length < text.length) {
const timeout = setTimeout(() => {
setDisplayedText(text.slice(0, displayedText.length + 1));
playSound('click');
}, speed);
return () => clearTimeout(timeout);
} else {
onComplete?.();
}
}, [displayedText, text, speed, isTyping, playSound, onComplete]);
return (
<span className={className}>
{displayedText}
{displayedText.length < text.length && (
<span className="animate-pulse"></span>
)}
</span>
);
};
export default TypingText;