react-ronin
Version:
Access the RONIN data platform via React.
97 lines (96 loc) • 4.35 kB
JavaScript
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;