Gutenberg List Extension Block

I’m trying to extend the default Gutenberg unordered list that renders like this;

<ul>
    <li>Item 1</li>
    <li>Item 2</li>
</ul>

To something like this when it has a custom list style attribute selected;

<ul>
    <li><span></span>Item 1</li>
    <li><span></span>Item 2</li>
</ul>

To do this I started setting up an extension with some custom attributes like this;

// Set up the list style attributes
const addListStyleAttribute = ( props, name ) => {
    if ( ! blocksSupportingListStyle.includes( name ) ) {
        return props;
    }

    // Add custom list attributes
    // 1. The style of the list that we want to assign
    // 2. A query to return the plain items in an array
    const attributes = {
        ...props.attributes,
        listStyle: {
            type: 'string',
            default: listStyleOptions[ 1 ].value,
        },
        listItems: {
            type: 'array',
            source: 'query',
            selector: 'li',
            query: {
                item: {
                    type: 'string',
                    source: 'text',
                    multiline: 'li',
                }
            }
        }
    }

    return { ...props, attributes };
};

addFilter( 'blocks.registerBlockType',  'fitsociety/list', addListStyleAttribute );

With the custom listitems nicely lined up in an array I thought I just create a custom element and render that by using the blocks.getSaveElement. The docs state that it can be used for that;

A filter that applies to the result of a block’s save function. This
filter is used to replace or extend the element, for example using
wp.element.cloneElement to modify the element’s props or replace its
children, or returning an entirely new element.

The filter’s callback receives an element, a block type and the block
attributes as arguments. It should return an element.

However when I set it up like this;

const setupCustomListStyle = ( element, blockType, blockAttributes ) => {

    if ( ! blocksSupportingListStyle.includes( blockType.name ) && ! blockType.attributes.listStyle ) {
        // console.log( "Content", blockAttributes);
        return element;

    } else {
        const customList = createElement(
            'ul',
            createElement(
                'li',
                {},
                createElement(
                    'span',
                    {}
                )
            )
        )

        return customList

    }
}

It doesn’t work because the save does not match the post. Which is correct of course. It is different but they state in the docs that you can render a completely custom element. I tried it using cloneElement but I can’t get the <span> inside the <li> that way.

0

Leave a Comment