Skip to content

Commit

Permalink
Merge pull request #148 from storyblok/bugfix/PRO-815-extra-wrapper-div
Browse files Browse the repository at this point in the history
fix: avoid rendering extra div on doc
  • Loading branch information
alvarosabu authored Nov 22, 2024
2 parents d1311ae + 869692e commit e17ff7e
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 9 deletions.
12 changes: 9 additions & 3 deletions playground/react/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ function convertStyleStringToObject(styleString: string) {
* @param {React.ReactElement} element The React element to process.
* @return {React.ReactElement} A new React element with converted attributes.
*/
export function convertAttributesInElement(element: React.ReactElement): React.ReactElement {
export function convertAttributesInElement(element: React.ReactElement | React.ReactElement[]): React.ReactElement | React.ReactElement[] {
if (Array.isArray(element)) {
return element.map(el => convertAttributesInElement(el)) as React.ReactElement[];
}

// Base case: if the element is not a React element, return it unchanged.
if (!React.isValidElement(element)) {
return element;
Expand All @@ -52,6 +56,8 @@ export function convertAttributesInElement(element: React.ReactElement): React.R
return acc;
}, {});

newProps.key = (element.key as string);

// Process children recursively.
const children = React.Children.map((element.props as React.PropsWithChildren).children, child => convertAttributesInElement(child));
const newElement = React.createElement(element.type, newProps, children);
Expand Down Expand Up @@ -464,11 +470,11 @@ function App() {
options,
).render(story.content.richtext);

// eslint-disable-next-line no-console
console.log(html);
// console.log(html);

const formattedHtml = convertAttributesInElement(html);

// console.log(formattedHtml);
return (
<>
{formattedHtml}
Expand Down
30 changes: 29 additions & 1 deletion playground/vanilla/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,34 @@ import './style.css';
import { MarkTypes, richTextResolver, type StoryblokRichTextNode, type StoryblokRichTextOptions } from '@storyblok/richtext';
import StoryblokClient from 'storyblok-js-client';

/* const test = {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'Hey ',
},
],
},
{
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'nested',
},
],
},
],
},
],
}; */
/* const doc: StoryblokRichTextDocumentNode = {
type: 'doc',
content: [
Expand Down Expand Up @@ -409,7 +437,7 @@ const options: StoryblokRichTextOptions<string> = {
const html = richTextResolver(options).render(docFromStory);

document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
<div>
<div class="this-div-is-on-purpose">
${html}
</div>
`;
2 changes: 0 additions & 2 deletions playground/vue/src/components/HomeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import type { VNode } from 'vue';
import { createTextVNode, h } from 'vue';
import { BlockTypes, richTextResolver, type StoryblokRichTextNode, type StoryblokRichTextOptions } from '@storyblok/richtext';
import { RouterLink } from 'vue-router';
import { useStoryblok } from '@storyblok/vue';
import CodeBlock from './CodeBlock.vue';
Expand Down Expand Up @@ -389,6 +388,5 @@ const root = () => richTextResolver<VNode>(options).render(story.value.content.r
</script>

<template>
<RouterLink to="http://alvarosaburido.dev">About</RouterLink>
<root />
</template>
36 changes: 36 additions & 0 deletions src/richtext.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,42 @@ import { BlockTypes, MarkTypes, type StoryblokRichTextNode, type StoryblokRichTe
import { StoryblokComponent } from '@storyblok/vue';

describe('richtext', () => {
describe('document', () => {
it('should not render any wrapper tag', () => {
const { render } = richTextResolver({});
const richdata = {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'Hey ',
},
],
},
{
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'nested',
},
],
},
],
},
],
};

const html = render(richdata as StoryblokRichTextNode<string>);
expect(html).toBe('<p>Hey </p><p>nested</p>');
});
});
describe('blocktypes', () => {
it('should render a paragraph', async () => {
const { render } = richTextResolver({});
Expand Down
14 changes: 11 additions & 3 deletions src/richtext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ import { attrsToString, attrsToStyle, cleanObject, escapeHtml, SELF_CLOSING_TAGS
function defaultRenderFn<T = string | null>(tag: string, attrs: Record<string, any> = {}, children?: T): T {
const attrsString = attrsToString(attrs);
const tagString = attrsString ? `${tag} ${attrsString}` : tag;
const content = Array.isArray(children) ? children.join('') : children || '';

if (SELF_CLOSING_TAGS.includes(tag)) {
if (!tag) {
return content as unknown as T;
}
else if (SELF_CLOSING_TAGS.includes(tag)) {
return `<${tagString}>` as unknown as T;
}
return `<${tagString}>${Array.isArray(children) ? children.join('') : children || ''}</${tag}>` as unknown as T;
return `<${tagString}>${content}</${tag}>` as unknown as T;
}

/**
Expand All @@ -40,6 +44,7 @@ export function richTextResolver<T>(options: StoryblokRichTextOptions<T> = {}) {
optimizeImages = false,
keyedResolvers = false,
} = options;
const isExternalRenderFn = renderFn !== defaultRenderFn;

const nodeResolver = (tag: string): StoryblokRichTextNodeResolver<T> =>
(node: StoryblokRichTextNode<T>): T => {
Expand Down Expand Up @@ -202,7 +207,7 @@ export function richTextResolver<T>(options: StoryblokRichTextOptions<T> = {}) {
};

const mergedResolvers = new Map<StoryblokRichTextNodeTypes, StoryblokRichTextNodeResolver<T>>([
[BlockTypes.DOCUMENT, nodeResolver('div')],
[BlockTypes.DOCUMENT, nodeResolver('')],
[BlockTypes.HEADING, headingResolver],
[BlockTypes.PARAGRAPH, nodeResolver('p')],
[BlockTypes.UL_LIST, nodeResolver('ul')],
Expand Down Expand Up @@ -276,6 +281,9 @@ export function richTextResolver<T>(options: StoryblokRichTextOptions<T> = {}) {
*
*/
function render(node: StoryblokRichTextNode<T>): T {
if (node.type === 'doc') {
return isExternalRenderFn ? node.content.map(renderNode) as T : node.content.map(renderNode).join('') as T;
}
return Array.isArray(node) ? node.map(renderNode) as T : renderNode(node) as T;
}

Expand Down

0 comments on commit e17ff7e

Please sign in to comment.