yarn-spinner-runner-ts
Version:
TypeScript parser, compiler, and runtime for Yarn Spinner 3.x with React adapter [NPM package](https://www.npmjs.com/package/yarn-spinner-runner-ts)
78 lines • 3.31 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState, useEffect, useRef } from "react";
import { MarkupRenderer } from "./MarkupRenderer.js";
export function TypingText({ text, markup, typingSpeed = 100, showCursor = true, cursorCharacter = "|", cursorBlinkDuration = 530, cursorClassName = "", className = "", onComplete, disabled = false, }) {
const [displayedLength, setDisplayedLength] = useState(disabled ? text.length : 0);
const [cursorVisible, setCursorVisible] = useState(true);
const cursorIntervalRef = useRef(null);
const typingTimeoutRef = useRef(null);
const onCompleteRef = useRef(onComplete);
useEffect(() => {
onCompleteRef.current = onComplete;
}, [onComplete]);
// Handle cursor blinking
useEffect(() => {
if (!showCursor || disabled) {
return;
}
cursorIntervalRef.current = setInterval(() => {
setCursorVisible((prev) => !prev);
}, cursorBlinkDuration);
return () => {
if (cursorIntervalRef.current) {
clearInterval(cursorIntervalRef.current);
}
};
}, [showCursor, cursorBlinkDuration, disabled]);
// Handle typing animation
useEffect(() => {
if (disabled) {
setDisplayedLength(text.length);
if (onCompleteRef.current && text.length > 0) {
onCompleteRef.current();
}
return;
}
// Reset when text changes
setDisplayedLength(0);
if (text.length === 0) {
if (onCompleteRef.current) {
onCompleteRef.current();
}
return;
}
let index = 0;
const typeNextCharacter = () => {
if (index < text.length) {
index += 1;
setDisplayedLength(index);
if (typingSpeed <= 0) {
requestAnimationFrame(typeNextCharacter);
}
else {
typingTimeoutRef.current = setTimeout(typeNextCharacter, typingSpeed);
}
}
else if (onCompleteRef.current) {
onCompleteRef.current();
}
};
if (typingSpeed <= 0) {
requestAnimationFrame(typeNextCharacter);
}
else {
typingTimeoutRef.current = setTimeout(typeNextCharacter, typingSpeed);
}
return () => {
if (typingTimeoutRef.current) {
clearTimeout(typingTimeoutRef.current);
}
};
}, [text, disabled, typingSpeed]);
const visibleLength = markup ? Math.min(displayedLength, markup.text.length) : Math.min(displayedLength, text.length);
return (_jsxs("span", { className: className, children: [_jsx("span", { children: markup ? (_jsx(MarkupRenderer, { text: text, markup: markup, length: visibleLength })) : (text.slice(0, visibleLength)) }), showCursor && !disabled && (_jsx("span", { className: `yd-typing-cursor ${cursorClassName}`, style: {
opacity: cursorVisible ? 1 : 0,
transition: `opacity ${cursorBlinkDuration / 2}ms ease-in-out`,
}, children: cursorCharacter }))] }));
}
//# sourceMappingURL=TypingText.js.map