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
Unfortunately the gutenberg developer handbook doesn't give much info / and I'm not seeing how should I do it.
Thanks and cheers
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
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
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/
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!
draggable
property from the<li>
. – Alvaro Commented Dec 14, 2018 at 23:46