Typewriter Text
Typewriter Text é um componente de texto para React e Tailwind CSS, da biblioteca SmoothUI, com licença MIT. Copia e cola no teu projeto.
SmoothUI
MIT
text
O que é
Typewriter Text é um componente de texto para React e Tailwind CSS, da biblioteca SmoothUI, com licença MIT. Copia e cola no teu projeto.
Como usar
Abre o componente no catálogo, carrega em copiar, e cola no teu projeto. O prompt copiado leva o código e as regras para o teu agente o reproduzir sem alterar nada.
Cinco cópias grátis por mês. Sem cartão.
Não precisa de pacotes além do que o projeto já tem
Licença
Este componente vem de SmoothUI e é redistribuído sob a licença MIT, que permite uso comercial. O aviso de copyright viaja com o código.
Typewriter Text
import type React from "react";
import { useEffect, useRef, useState } from "react";
function useReducedMotion() {
const [shouldReduceMotion, setShouldReduceMotion] = useState(false);
useEffect(() => {
const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
setShouldReduceMotion(mediaQuery.matches);
const handleChange = (e: MediaQueryListEvent) => {
setShouldReduceMotion(e.matches);
};
mediaQuery.addEventListener("change", handleChange);
return () => mediaQuery.removeEventListener("change", handleChange);
}, []);
return shouldReduceMotion;
}
export interface TypewriterTextProps {
children: string;
className?: string;
loop?: boolean;
speed?: number;
}
const LOOP_RESTART_DELAY_MS = 1000;
const TypewriterText: React.FC<TypewriterTextProps> = ({
children,
speed = 50,
loop = false,
className = "",
}) => {
const [displayed, setDisplayed] = useState("");
const index = useRef(0);
const timeout = useRef<NodeJS.Timeout | null>(null);
const shouldReduceMotion = useReducedMotion();
useEffect(() => {
if (shouldReduceMotion) {
// Show full text immediately when reduced motion is enabled
setDisplayed(children);
return;
}
setDisplayed("");
index.current = 0;
function type() {
setDisplayed(children.slice(0, index.current + 1));
if (index.current < children.length - 1) {
index.current++;
timeout.current = setTimeout(type, speed);
} else if (loop) {
timeout.current = setTimeout(() => {
setDisplayed("");
index.current = 0;
type();
}, LOOP_RESTART_DELAY_MS);
}
}
type();
return () => {
if (timeout.current) {
clearTimeout(timeout.current);
}
};
}, [children, speed, loop, shouldReduceMotion]);
return <span className={className}>{displayed}</span>;
};
export default TypewriterText;