Skip to content

Instantly share code, notes, and snippets.

@miklosme
Created February 3, 2022 19:55
Show Gist options
  • Save miklosme/68e79a9c91139cb8a374845010b0ccc6 to your computer and use it in GitHub Desktop.
Save miklosme/68e79a9c91139cb8a374845010b0ccc6 to your computer and use it in GitHub Desktop.
import type { ComponentType } from "react"
import { useState, useEffect } from "react"
function useTyping(str, speed = 20) {
const [pos, setPos] = useState(0)
useEffect(() => {
let i = 0
let interval = setInterval(() => {
if (i < str.length) {
setPos(++i)
} else {
clearInterval(interval)
}
}, speed)
return () => clearInterval(interval)
}, [str])
return str.slice(0, pos)
}
export function withTypingEffect(Component): ComponentType {
return (props: any) => {
const parsed = new DOMParser().parseFromString(
props.rawHTML,
"text/html"
)
const text = parsed.body.innerText
const animatedText = useTyping(text)
const newHTML = props.rawHTML.replace(text, animatedText)
return <Component {...props} rawHTML={newHTML} />
}
}
// rawHTML:
// <span style='font-size: 0; line-height: 0; tab-size: 4; white-space: inherit; word-wrap: inherit'><span style='direction: ltr; font-size: 0'><span style='background-color: rgba(128,128,128,0.33)'>Hello foo bar baz typing yolo test test</span><br></span></span>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment