JSFiddle - React, Tailwind, and code Playground
HTML
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="app"></div>
CSS
.xxx {
font: bold 24px monospace;
}
Babel + JSX
const { useState, useRef, useEffect } = React;
const defaults = {
index: 0,
length: 0,
step: 1,
};
function Typewriter({ strings, delay }) {
const [ state, setState ] = useState(null);
useEffect(() => {
setState(() => ({...defaults}));
}, [ strings ]);
useEffect(() => {
const timeoutId = setTimeout(setState, delay, ({...state}) => {
state.length += state.step;
if (state.length === strings[state.index].length) {
state.step = -1;
} else if (state.length === 0) {
state.step = 1;
state.index = (state.index + 1) % strings.length;
}
return state;
});
return () => clearTimeout(timeoutId);
});
return <div className="xxx">{strings?.[state?.index]?.slice(0, state?.length)}</div>;
}
function App() {
const stringsOptions = useRef([
[ 'hello, world!!', 'fuck the world', 'fuck everything' ],
[ '69', '187', '666' ],
[ 'lorem', 'ipsum', 'dolor', 'sit', 'amet' ],
]);
const [ stringsIndex, setStringsIndex ] = useState(0);
const [ delay, setDelay ] = useState(100);
return (
<div>
<div>
strings:
<select value={stringsIndex} onChange={e => setStringsIndex(+e.target.value)}>
{stringsOptions.current.map((n, i) => <option value={i}>{n[0]}...</option>)}
</select>
</div>
<div>
delay:
<input
type="range"
min="10"
max="500"
step="10"
value={delay}
onChange={e => setDelay(+e.target.value)}
/>
{delay} ms
</div>
<Typewriter strings={stringsOptions.current[stringsIndex]} delay={delay} />
</div>
)
}
ReactDOM.createRoot(document.querySelector('#app')).render(<App />);