nuxt-strapi-blocks-renderer
Version:
Renderer for the strapi CMS blocks text content element.
100 lines (99 loc) • 3.68 kB
JavaScript
import { h, resolveComponent } from "vue";
const getNodeText = (node) => {
const lines = [];
node.text.split("\n").forEach((line, index, array) => {
lines.push(line);
if (index !== array.length - 1) {
lines.push(h("br"));
}
});
return lines;
};
export const textInlineNode = (node, prefix) => {
const text = getNodeText(node);
if (node.bold) return h(resolveComponent(`${prefix}BoldInlineNode`), () => text);
if (node.italic) return h(resolveComponent(`${prefix}ItalicInlineNode`), () => text);
if (node.underline) return h(resolveComponent(`${prefix}UnderlineInlineNode`), () => text);
if (node.strikethrough) return h(resolveComponent(`${prefix}StrikethroughInlineNode`), () => text);
if (node.code) return h(resolveComponent(`${prefix}CodeInlineNode`), () => text);
return text;
};
export const linkInlineNode = (node, prefix) => {
const linkComponent = resolveComponent(`${prefix}LinkInlineNode`);
return h(linkComponent, { url: node.url }, () => node.children.map((childNode) => {
return textInlineNode(childNode, prefix);
}));
};
export const defaultInlineNode = (node, prefix) => {
if (node.type === "link") {
return linkInlineNode(node, prefix);
} else if (node.type === "text") {
return textInlineNode(node, prefix);
}
};
export const listItemInlineNode = (node, prefix) => {
const listItemComponent = resolveComponent(`${prefix}ListItemInlineNode`);
return h(listItemComponent, () => node.children.map(
(childNode) => defaultInlineNode(childNode, prefix)
));
};
export const headingBlockNode = (node, prefix) => {
const headingComponent = resolveComponent(`${prefix}Heading${node.level}Node`);
return h(headingComponent, () => node.children.map(
(childNode) => defaultInlineNode(childNode, prefix)
));
};
export const paragraphBlockNode = (node, prefix) => {
const paragraphComponent = resolveComponent(`${prefix}ParagraphNode`);
return h(paragraphComponent, () => node.children.map(
(childNode) => defaultInlineNode(childNode, prefix)
));
};
export const codeBlockNode = (node, prefix) => {
const codeComponent = resolveComponent(`${prefix}CodeNode`);
return h(codeComponent, () => node.children.map(
(childNode) => textInlineNode(childNode, prefix)
));
};
export const quoteBlockNode = (node, prefix) => {
const quoteComponent = resolveComponent(`${prefix}QuoteNode`);
return h(quoteComponent, () => node.children.map(
(childNode) => defaultInlineNode(childNode, prefix)
));
};
export const listBlockNode = (node, prefix) => {
const listType = node.format === "ordered" ? "OrderedListNode" : "UnorderedListNode";
const listComponent = resolveComponent(`${prefix}${listType}`);
return h(listComponent, () => node.children.map(
(childNode) => {
if (childNode.type === "list-item") {
return listItemInlineNode(childNode, prefix);
}
return listBlockNode(childNode, prefix);
}
));
};
export const imageBlockNode = (node, prefix) => {
const imageComponent = resolveComponent(`${prefix}ImageNode`);
return h(imageComponent, {
image: node.image
});
};
export const renderBlocks = (blockNodes, prefix) => {
return blockNodes.map((blockNode) => {
switch (blockNode.type) {
case "heading":
return headingBlockNode(blockNode, prefix);
case "code":
return codeBlockNode(blockNode, prefix);
case "list":
return listBlockNode(blockNode, prefix);
case "quote":
return quoteBlockNode(blockNode, prefix);
case "image":
return imageBlockNode(blockNode, prefix);
default:
return paragraphBlockNode(blockNode, prefix);
}
});
};