react – How can I render a built-in Gutenberg block with InnerBlocks outside of the block editor?
I want to show my custom styling for some built-in blocks in my project’s Storybook instance. I have it working great for simple blocks. To show the Paragraph block, I do this:
Paragraph.stories.jsx
:
import ParagraphBlock from 'wordpress user/block-library/build-module/paragraph/save';
import templateFromBlock from './templateFromWordPressBlock';
export default {
title: 'Default/Paragraph',
component: ParagraphBlock,
argTypes: {
attributes: {
control: 'object'
},
},
parameters: {
layout: 'padded',
},
};
const Template = templateFromBlock('paragraph', ParagraphBlock);
export const Paragraph = Template.bind({});
Paragraph.args = {
attributes: {
content: 'Lorem ipsum dolor sit amet, <em>consectetur adipisicing elit</em>, sed do <strong>eiusmod tempor incididunt</strong> ut labore et dolore magna aliqua. <a href="https://google.com">Ut enim ad minim</a> veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
}
};
templateFromWordPressBlock.js
:
// The getSaveElement technique is courtesy of https://github.com/WordPress/gutenberg/issues/37988.
import { getSaveElement } from 'wordpress user/blocks';
import { renderToString, RawHTML } from 'wordpress user/element';
import '../../../../../wp-includes/css/classic-themes.min.css';
import '../../../../../wp-includes/css/dist/block-library/style.css';
import '../../../../themes/my-theme/src/style.scss';
export const blockContent = (name, Block, args) => {
getSaveElement({ name: name, save: Block }, args.attributes);
return <RawHTML>{renderToString(<Block {...args} />)}</RawHTML>;
};
export default (name, Block) => {
return args => {
return blockContent(name, Block, args);
};
};
It works!
However, this falls down when using a block with InnerBlocks, such as the Quote block. I have tried a few different ways of passing children to the Quote block’s save
component, but none of them did anything good. The Citation shows up, since it’s entirely based on attributes; but I’ve never gotten a single character to render where the InnerBlocks go.
I gather that the InnerBlocks
component expects to have a Redux store or some other data source to pull InnerBlocks data from, not just props/attributes on the component/block. I am currently looking to see what the developer of BlockBook did before abandoning the project, but it’s a bit of a rabbit hole, so I thought I’d ask, in case it ends up being faster: How can I provide a block’s InnerBlocks without scaffolding the entire block editor?
Leave an answer