Frontend developer focused on inclusive design

Inner blocks in WordPress

InnerBlocks is a component in WordPress Block Editor that allows to add and remove blocks inside a parent block. The component also comes with support for drag-and-drop reordering functionality.

It's a useful tool for creating flexible and dynamic functionality for the Block Editor.

Orientation

The component automatically provides with Block Movers in toolbar, allowing to move inner blocks within a parent block. The toolbar control has two styles. It either displays arrows up and down or left to right.

The InnerBlocks component allows to set orientation for child blocks:

/**
 * Define the block layout as 'grid'.
 */
const blockLayout = 'grid';

/**
 * Get the block properties object using the useBlockProps() hook.
 */
const blockProps = useBlockProps();

/**
 * Get the inner blocks properties object using the useInnerBlocksProps() hook.
 * Pass in the block properties object and an options object as arguments.
 */
const innerBlocksProps = useInnerBlocksProps(blockProps, {

  /**
   * Set the orientation property based on the value of the blockLayout variable.
   * If the blockLayout is 'grid', set the orientation to 'horizontal',
   * otherwise set it to 'vertical'.
   */
  orientation: blockLayout === 'grid' ? 'horizontal' : 'vertical',
});

In code example above, InnerBlocks component changes orientation, depending on set layout.

Use horizontal or vertical to set inner blocks' orientation.

Allowed blocks

Working with the InnerBlocks component may present challenges when dealing with allowed blocks, particularly when using the useInnerBlocksProps hook in conjunction with the InnerBlocks component.

This hook merges custom properties with existing block properties, potentially causing conflicts or unexpected behavior when enforcing allowed blocks.

To address this issue, it is important to note that when using the useInnerBlocksProps hook, the innerBlocksProps.children property should be utilized instead of the <InnerBlocks> component.

The following example demonstrates this:

/**
 * Define the allowed blocks array, which specifies the block types allowed
 * inside the InnerBlocks component. In this case, only "core/heading" and
 * "core/paragraph" blocks are allowed.
 */
const ALLOWED_BLOCKS = [
	"core/heading",
	"core/paragraph",
];

/**
 * Create the innerBlocksProps by calling the useInnerBlocksProps hook.
 * Pass the existing blockProps and an object with additional properties.
 * Here, allowedBlocks is set to the ALLOWED_BLOCKS array, and the
 * orientation is set to "horizontal".
 */
const innerBlocksProps = useInnerBlocksProps(blockProps, {
	allowedBlocks: ALLOWED_BLOCKS,
	orientation: "horizontal",
});

/**
 * Render the containing div element and spread the innerBlocksProps on it.
 * This will ensure that all properties from the useInnerBlocksProps hook
 * are applied to the div element.
 * Additionaly, render the children of the InnerBlocks component using the
 * innerBlocksProps.children property. This will enforce the allowed
 * blocks constraint and ensure that only the specified blocks can
 * be added inside the InnerBlocks component.
 */
return (
	<div { ...innerBlocksProps }>
		{ innerBlocksProps.children }
	</div>
);

By incorporating innerBlocksProps.children in the code above, the allowed blocks constraint is enforced as intended. This approach helps to avoid issues that may arise due to property merging conflicts.