Skip to content

Commit

Permalink
feat: context prop to BlocksRenderer
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasio committed Jul 17, 2024
1 parent 852541d commit 50b8dfb
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
20 changes: 19 additions & 1 deletion packages/core/src/react/components/BaseBlocksRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ const { default: parse, domToReact } = HtmlReactParser;
/**
* The interface any children of {@link BlocksRenderer} must implement.
*/
export interface BlockProps<BlockAttributes extends IDataWPBlock = IDataWPBlock> {
export interface BlockProps<
BlockAttributes extends IDataWPBlock = IDataWPBlock,
Context extends Record<string, unknown> = Record<string, unknown>,
> {
/**
* A test function receives a domNode and returns a boolean value indicating
* whether that domNode should be replaced with the React component
Expand Down Expand Up @@ -64,6 +67,11 @@ export interface BlockProps<BlockAttributes extends IDataWPBlock = IDataWPBlock>
* The style tag of the domNode as an object.
*/
style?: Record<string, string>;

/**
* An optional context that is passed to all children components
*/
context?: Context;
}

/**
Expand Down Expand Up @@ -121,6 +129,11 @@ export interface BlockRendererProps {
* Whether to forward the block attributes to the children components.
*/
forwardBlockAttributes?: boolean;

/**
* An optional context that is passed to all children components
*/
context?: Record<string, unknown>;
}

interface BaseBlockRendererProps extends BlockRendererProps {
Expand Down Expand Up @@ -153,6 +166,7 @@ export function BaseBlocksRenderer({
children,
settings,
forwardBlockAttributes = false,
context,
}: BaseBlockRendererProps) {
const blocks: ReactNode[] = React.Children.toArray(children);

Expand Down Expand Up @@ -216,6 +230,10 @@ export function BaseBlocksRenderer({
blockProps.block = { attributes, name, className };
}

if (context) {
blockProps.context = context;
}

component = React.createElement(
block.type,
blockProps,
Expand Down
25 changes: 25 additions & 0 deletions packages/core/src/react/components/__tests__/BlocksRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -239,4 +239,29 @@ describe('BlocksRenderer', () => {

expect(container).toMatchSnapshot();
});

it('forward context to the component', () => {
const DivToP = ({
block,
context,
}: BlockProps<{ blockAttribute: string }, { contextProp: string }>) => {
return (
<p className={block?.className}>
{JSON.stringify(block)} - {JSON.stringify(context)}
</p>
);
};

const { container } = render(
<BlocksRenderer
html={`<div class="my-class" data-wp-block-name='10up/custom-block' data-wp-block='${JSON.stringify({ blockAttribute: 'this is a block attribute' })}'></div>`}
forwardBlockAttributes
context={{ contextProp: 'this is a context prop' }}
>
<DivToP test={(node) => isBlockByName(node, '10up/custom-block')} />
</BlocksRenderer>,
);

expect(container).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ exports[`BlocksRenderer forward blockProps to the component 1`] = `
</div>
`;

exports[`BlocksRenderer forward context to the component 1`] = `
<div>
<p
class="my-class"
>
{"attributes":{"blockAttribute":"this is a block attribute"},"name":"10up/custom-block","className":"my-class"}
-
{"contextProp":"this is a context prop"}
</p>
</div>
`;

exports[`BlocksRenderer works correctly with chinese content 1`] = `
<div>
<h3
Expand Down

0 comments on commit 50b8dfb

Please sign in to comment.