Files
payload/examples/form-builder/nextjs/components/RichText/serialize.tsx

161 lines
2.7 KiB
TypeScript

import React, { Fragment } from 'react';
import escapeHTML from 'escape-html';
import { Text } from 'slate';
// eslint-disable-next-line no-use-before-define
type Children = Leaf[]
type Leaf = {
type: string
value?: {
url: string
alt: string
}
children?: Children
url?: string
[key: string]: unknown
}
const serialize = (children: Children): React.ReactElement[] => children.map((node, i) => {
if (Text.isText(node)) {
let text = <span dangerouslySetInnerHTML={{ __html: escapeHTML(node.text) }} />;
if (node.bold) {
text = (
<strong key={i}>
{text}
</strong>
);
}
if (node.code) {
text = (
<code key={i}>
{text}
</code>
);
}
if (node.italic) {
text = (
<em key={i}>
{text}
</em>
);
}
if (node.underline) {
text = (
<span
style={{ textDecoration: 'underline' }}
key={i}
>
{text}
</span>
);
}
if (node.strikethrough) {
text = (
<span
style={{ textDecoration: 'line-through' }}
key={i}
>
{text}
</span>
);
}
return (
<Fragment key={i}>
{text}
</Fragment>
);
}
if (!node) {
return null;
}
switch (node.type) {
case 'h1':
return (
<h1 key={i}>
{serialize(node.children)}
</h1>
);
case 'h2':
return (
<h2 key={i}>
{serialize(node.children)}
</h2>
);
case 'h3':
return (
<h3 key={i}>
{serialize(node.children)}
</h3>
);
case 'h4':
return (
<h4 key={i}>
{serialize(node.children)}
</h4>
);
case 'h5':
return (
<h5 key={i}>
{serialize(node.children)}
</h5>
);
case 'h6':
return (
<h6 key={i}>
{serialize(node.children)}
</h6>
);
case 'blockquote':
return (
<blockquote key={i}>
{serialize(node.children)}
</blockquote>
);
case 'ul':
return (
<ul key={i}>
{serialize(node.children)}
</ul>
);
case 'ol':
return (
<ol key={i}>
{serialize(node.children)}
</ol>
);
case 'li':
return (
<li key={i}>
{serialize(node.children)}
</li>
);
case 'link':
return (
<a
href={escapeHTML(node.url)}
key={i}
>
{serialize(node.children)}
</a>
);
default:
return (
<p key={i}>
{serialize(node.children)}
</p>
);
}
});
export default serialize;