3

I'm developing some custom blocks in the new Gutenberg editor experience, and I'm struggle to understand how to use some build-in components, mostly the Draggable components.

What I would like to achieve is a list of items (let's say many li in a ul) and I want them to be orderable with a drag & drop feature.

Here is my code:

import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { Draggable, Dashicon } from '@wordpress/components';

import './style.scss';
import './editor.scss';

registerBlockType( 'namespace/my-custom-block', 
{
    title: __( 'Custom block', 'namespace'),
    description: __( 'Description of the custom block', 'namespace' ),
    category: 'common',
    icon: 'clipboard',
    keywords: [
    __( 'list', 'namespace' ),
    __( 'item', 'namespace' ),
    __( 'order', 'namespace' )
    ],
    supports: {
    html: false,
    multiple: false,
    },
    attributes: {
        items: {
            type: 'array',
            default: [ 'One' ,'Two' ,'Tree' ,'Four' ,'Five' ,'Six' ,'Seven' ,'Eight' ,'Nine' ,'Ten' ]
        }
    },
    edit: props => {
    return (
        <ul>
        { props.attributes.items.map( (itemLabel, id) => (
            <li id={ `li_${id}` } draggable>
            <Draggable
                elementId={ `li_${id}` }
                transferData={ {} }>
                {
                ({ onDraggableStart, onDraggableEnd }) => (
                    <Dashicon
                    icon="move"
                    onDragStart={ onDraggableStart }
                    onDragEnd={ onDraggableEnd }
                    draggable
                    />
                )
                }
            </Draggable>
            { itemLabel }
            </li>
        ))
        }
        </ul>
    )
    },
    save: () => {
    // Return null to be rendered on the server
    return null;
    }
}
)

On the backend side it is correctly rendered but the items are not draggable

enter image description here

Unfortunately the gutenberg developer handbook doesn't give much info https://wordpress.org/gutenberg/handbook/designers-developers/developers/components/draggable/ and I'm not seeing how should I do it.

Thanks and cheers

3
  • I don't know the answer to your question, but an alternative might instead be to have child blocks and whitelist a second block type, then you could drag and drop them via the GB editor controls instead
    – Tom J Nowell
    Dec 14, 2018 at 23:31
  • Adding extra drag inside a block might create conflicts. Possibly the drop area of the block overlays the block content when a drag starts. Also, remove the draggable property from the <li>.
    – Alvaro
    Dec 14, 2018 at 23:46
  • noting that since this was written, list blocks themselves and others in WP core are transitioning to being child blocks, with the ability to drag and drop being a new selling point of this.
    – Tom J Nowell
    Oct 5, 2022 at 13:42

2 Answers 2

0

If you need to make something drag and drop that appears inside your block in the main content area, then you should use child blocks to implement that, and the <InnerBlocks/> component. You can then force the inner blocks so that they can only be your new child block type.

For example we could have a kuuak/my-custom-block block, and each draggable item would be a kuuak/my-custom-block-item. Then you could use this to allow items to be inserted and sorted, but only your item block, nothing else:

const ALLOWED_BLOCKS = [ 'kuuak/my-custom-block-item' ];
//...
<InnerBlocks allowedBlocks={ ALLOWED_BLOCKS } />;

You can also force it so that item blocks can't be used anywhere else block type when registering:

"parent": [ "kuuak/my-custom-block" ],

This pattern is used in a lot of WordPress core blocks, e.g. a columns block that can only contain "column" blocks, the new gallery blocks that act as containers for individual image blocks, carousels, etc

Further reading on nested/inner blocks: https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/nested-blocks-inner-blocks/

1
  • noting that core itself now uses a similar pattern to this internally for list blocks
    – Tom J Nowell
    Mar 5, 2023 at 16:58
-1

Use react-sortable-hoc Draggable is lacking documentation and I did not had the time to dig into it. But the above is for you. I used it to create the sidebar Entry Content/Primary Sidebar control - used to reorder my theme content/sidebar! 2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.