The WordPress Block Editor has a number of filters to let us extend a given block but the documentation left me scratching my head. I had a project where I needed to add style variation to headings and paragraphs that added a little decorative line above the block. Then we needed a control to set the color of that line.
Step 1: Register a Block Style Variation
You can do this in register_block_style() in PHP or in JS with wp.blocks.registerBlockStyle().
Step 2: Add additional attributes to the block
Make use of the blocks.registerBlockType filter to add attributes to settings.attributes and then return settings.
Step 3: Add additional controls to the editor
Make use of the editor.BlockEdit filter. This is probably the most complicated step. In my case I had to use compose() to first createHigherOrderComponent() of the BlockEdit component and then pass that to withColors() so my custom attribute is treated like most other colors.
The createHigherOrderComponent() takes the BlockEdit component and adds the custom control which sets the value on the attributes added to the block(s) in step 2.
Step 4: Add styles to the editor
With values in the attributes, use the editor.BlockListBlock filter to turn your attributes into the necessary inline-styles in the editor. The trick, at least for inline styles, is to use wrapperProps. This took way too much StackOverflow snorkeling to solve.
const applyOverlineEditorStyle = createHigherOrderComponent( ( BlockListBlock ) => {
return ( props ) => {
if ( ! enableOverlineColorOnBlocks.includes( props.name ) ) {
return <BlockListBlock {...props} />;
}
const { overlineColor, customOverlineColor } = props.attributes;
const wrapperProps = {
...props.wrapperProps,
'style': { '--wp--custom--overline-color': overlineColor
? `var( --wp--preset--color--${ overlineColor } )`
: customOverlineColor
}
}
return <BlockListBlock { ...props } wrapperProps={ wrapperProps }/>;
};
}, 'applyOverlineEditorStyle' );
addFilter(
'editor.BlockListBlock',
'namespace/overline-apply-editor-style',
applyOverlineEditorStyle
)Step 5: Add styles to the front end
The front end requires yet another filter, blocks.getSaveContent.extraProps. Here you can just add inline styles to props.style. Do watch out that you’re now potentially changing the saved content of a block so you can cause deprecation warnings.