StreamText
Character-by-character streaming text simulation with blinking cursor. Optionally loops.
Use and inspectUse this as a presentational interface around your own submit, stream, or state handlers. Reset preview only remounts the local example; it does not send a request or connect to a model.Next: inspect the source and wire its callback to a bounded backend action.
StreamTextCharacter-by-character streaming text simulation with blinking cursor. Optionally loops.
"use client";
import { useState, useEffect } from "react";
type StreamTextProps = {
text: string;
speed?: number;
loop?: boolean;
pauseMs?: number;
};
export function StreamText({
text,
speed = 28,
loop = false,
pauseMs = 1200,
}: StreamTextProps) {
const [displayed, setDisplayed] = useState("");
const [done, setDone] = useState(false);
useEffect(() => {
setDisplayed("");
setDone(false);
let i = 0;
const id = setInterval(() => {
if (i < text.length) {
setDisplayed(text.slice(0, i + 1));
i++;
} else {
setDone(true);
clearInterval(id);
if (loop) {
setTimeout(() => {
setDisplayed("");
setDone(false);
i = 0;
}, pauseMs);
}
}
}, speed);
return () => clearInterval(id);
}, [text, speed, loop, pauseMs]);
return (
<span>
{displayed}
{!done && <span aria-hidden="true">▋</span>}
</span>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
text* | string | — | The full text to stream |
speed | number | 28 | Milliseconds between characters |
loop | boolean | false | Restart after completion |
pauseMs | number | 1200 | Pause before looping (ms) |