UNPKG

react-ronin

Version:

Access the RONIN data platform via React.

97 lines (96 loc) 4.35 kB
import React, {} from "react"; const RichText = ({ data, components, }) => { const items = Array.isArray(data) ? data : [data]; return items.map((item, position) => { if (item.type === "text") { return (item.marks || []).reduce((final, mark) => { let Element = null; let attributes = {}; switch (mark.type) { case "bold": Element = components?.b || "b"; break; case "italic": Element = components?.i || "i"; break; case "code": Element = components?.code || "code"; break; case "link": Element = components?.a || "a"; if ("attrs" in mark) { attributes = { // We're selecting these properties individually because the // last one must be renamed. href: mark.attrs.href, rel: mark.attrs.rel, target: mark.attrs.target, className: mark.attrs.class, }; } break; } const RenderingElement = Element; return RenderingElement ? (React.createElement(RenderingElement, { ...attributes, key: (typeof RenderingElement === "string" ? RenderingElement : RenderingElement.name) + String(position) }, final)) : (final); }, item.text); } const richtTextPrefix = "rich-text-"; let Element = null; let children = item.content ? (React.createElement(RichText, { data: item.content, components: components, key: richtTextPrefix + String(position) })) : null; let language; switch (item.type) { case "doc": Element = components?.div || "div"; break; case "paragraph": Element = components?.p || "p"; break; case "blockquote": Element = components?.blockquote || "blockquote"; break; case "heading": if (item.attrs.level === 1) Element = components?.h1 || "h1"; if (item.attrs.level === 2) Element = components?.h2 || "h2"; if (item.attrs.level === 3) Element = components?.h3 || "h3"; if (item.attrs.level === 4) Element = components?.h4 || "h4"; break; case "codeBlock": { Element = components?.pre || "pre"; // Marks are not allowed within code blocks, so we can pick its text // children directly, to avoid having to render React elements for // each line of code. language = typeof item?.attrs.language === "undefined" || item.attrs.language === "null" || item.attrs.language === null ? "plaintext" : item?.attrs.language; const firstChild = item.content?.[0]; children = firstChild && "text" in firstChild ? firstChild?.text : null; } break; case "bulletList": Element = components?.ul || "ul"; break; case "listItem": Element = components?.li || "li"; break; case "orderedList": Element = components?.ol || "ol"; break; } const RenderingElement = Element; return RenderingElement ? (React.createElement(RenderingElement, { key: (typeof RenderingElement === "string" ? RenderingElement : RenderingElement.name) + String(position), language: language }, children)) : (children); }); }; export default RichText;