Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 44x 2x | import { createElement, ReactNode } from "react"; type FormatFunction = (str: string) => string | ReactNode[]; export function htmlToReact( htmlString: string, format: FormatFunction = (str) => str ?? "" ): ReactNode { const parser = new DOMParser(); const doc = parser.parseFromString(htmlString, "text/html"); const body = doc.body; const div = document.createElement("div"); Array.from(body.childNodes).forEach((child) => div.appendChild(child)); function traverse(node: Node): ReactNode { if (node.nodeType === Node.TEXT_NODE) { return format((node as Text).textContent ?? ""); } else Iif (node.nodeType === Node.ELEMENT_NODE) { const children = Array.from(node.childNodes).map(traverse); const props: Record<string, string> = {}; Array.from((node as Element).attributes).forEach((attr) => { props[attr.name] = attr.value; }); return createElement( (node as Element).tagName.toLowerCase(), props, ...children ); } return null; } return traverse(div); } |