@mikhail2404/react-ts-typewriter
Version:
React typewriter component written in TypeScript with React 18
77 lines (76 loc) • 3.53 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import React, { useState, useEffect } from 'react';
import styles from './Typewriter.module.css';
const DEFAULT_MS = 30;
export default function Typewriter({ text, speed = DEFAULT_MS, loop = false, newLine = false, random = DEFAULT_MS, delay = DEFAULT_MS, cursor = true, onFinished = () => {
}, onStart = () => {
} }) {
const [currentStringIndex, setCurrentStringIndex] = useState(0);
const [currentTextIndex, setCurrentTextIndex] = useState(0);
const [lines, setLines] = useState([text[0]]);
if (!Array.isArray(text))
text = [text];
useEffect(() => {
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
if (currentTextIndex === 0)
onStart();
if (currentTextIndex < text[currentStringIndex].length) {
setCurrentTextIndex(currentTextIndex + 1);
}
else {
if (currentStringIndex < text.length - 1) {
yield nextLine();
}
else {
if (loop) {
setTimeout(() => {
setCurrentTextIndex(0);
setCurrentStringIndex(0);
setLines([text[0]]);
}, delay);
}
else {
onFinished();
}
}
}
}), speed + (Math.random() * random));
});
const waitForDelay = (milisec) => {
return new Promise(resolve => {
setTimeout(() => {
resolve('');
}, milisec);
});
};
const typeWrite = (str) => __awaiter(this, void 0, void 0, function* () {
for (let i = 0; i < str.length; i++) {
yield waitForDelay(speed + (Math.random() * random));
setCurrentTextIndex(i);
}
});
const nextLine = () => __awaiter(this, void 0, void 0, function* () {
yield waitForDelay(delay);
setCurrentTextIndex(0);
setCurrentStringIndex(currentStringIndex + 1);
setLines(lines => [...lines, text[currentStringIndex + 1]]);
});
if (Array.isArray(text) && newLine && delay) {
return (React.createElement(React.Fragment, null,
lines.map((line, index) => (React.createElement("span", { key: index },
line === text[currentStringIndex] ? line.substring(0, currentTextIndex) : line,
currentStringIndex !== index && React.createElement("br", null)))),
React.createElement("span", { className: styles.cursor }, cursor && '▎')));
}
return (React.createElement("span", null,
text[currentStringIndex].substring(0, currentTextIndex),
React.createElement("span", { className: styles.cursor }, cursor && '▎')));
}