feat: add custom drag layer for enhanced drag-and-drop experience in editor
[!CAUTION] The Volto Team has suspended its review of new pull requests from first-time contributors until the release of Plone 7, which is preliminarily scheduled for the second quarter of 2026. Read details.
- [ ] I signed and returned the Plone Contributor Agreement, and received and accepted an invitation to join a team in the Plone GitHub organization.
- [ ] I verified there aren't other open pull requests for the same change.
- [ ] I followed the guidelines in Contributing to Volto.
- [ ] I succesfully ran code linting checks on my changes locally.
- [ ] I succesfully ran unit tests on my changes locally.
- [ ] I succesfully ran acceptance tests on my changes locally.
- [ ] If needed, I added new tests for my changes.
- [ ] If needed, I added documentation for my changes, either in the Storybook or narrative documentation.
- [ ] I included a change log entry in my commits.
If your pull request closes an open issue, include the exact text below, immediately followed by the issue number. When your pull request gets merged, then that issue will close automatically.
Closes #
Notes:
- Introduced
CustomDragLayercomponent to visually represent items being dragged. - Integrated
CustomDragLayerintoPlateEditorfor improved user feedback during drag operations. - Updated
Draggablecomponent to support drag previews and adjusted styles for better UI consistency.
The CustomDragLayer component currently renders only a text-element preview, just to show how we can override the browser’s default drag-and-drop preview. If you want the preview to show the actual content being dragged, you can:
Give the element a type prop when you render it in the editor.
Inside CustomDragLayer, read that type and render the same (or any other) component accordingly.
References Assign a type to the element you’re rendering
https://platejs.org/docs/dnd#usedraggable-opt-type
Read the type in the drag layer to decide what to render in the preview monitor.getItemType():
const { isDragging, item, itemType, currentOffset } = useDragLayer((monitor) => ({
item: monitor.getItem(),
itemType: monitor.getItemType(),
isDragging: monitor.isDragging(),
currentOffset: monitor.getClientOffset(),
}));