Le glisser-déposer d’un bloc dans l’éditeur donne une impression de simplicité trompeuse : on saisit un bloc, on le déplace, il se réinsère ailleurs. Derrière ce geste, plusieurs composants distincts du paquet @wordpress/block-editor coopèrent, sans qu’aucun d’eux ne manipule directement le DOM pour repositionner le contenu final.
Comprendre cette mécanique aide à diagnostiquer les rares bugs de réordonnancement, et surtout à savoir où intervenir si l’on souhaite personnaliser ce comportement pour un bloc composite maison.
Le rôle du composant Draggable
Le composant Draggable, exposé par @wordpress/components, se limite à capturer les événements natifs du navigateur liés au glisser (dragstart, drag, dragend) et à exposer des coordonnées de position en temps réel via une fonction de rendu enfant :
import { Draggable } from '@wordpress/components';
<Draggable elementId="mon-bloc" transferData={ { blockId } }>
{ ( { onDraggableStart, onDraggableEnd } ) => (
<div
draggable
onDragStart={ onDraggableStart }
onDragEnd={ onDraggableEnd }
>
Poignée de déplacement
</div>
) }
</Draggable>
Draggable ne sait rien de la structure de blocs : il transporte simplement une donnée (transferData) associée au geste, ici l’identifiant du bloc concerné. La logique de réordonnancement réelle se trouve ailleurs.
Le calcul de position via le magasin de données

Pendant le déplacement, une zone de dépôt (généralement un composant interne lié à BlockListBlock) calcule en continu, à partir de la position du curseur, où le bloc déplacé devrait s’insérer. Ce calcul ne modifie rien tant que le geste n’est pas terminé : il ne fait qu’afficher un indicateur visuel, une ligne fine qui matérialise le point d’insertion prévu.
Ce n’est qu’au relâchement du bouton (dragend) que l’action réelle est déclenchée, via le magasin de données core/block-editor et sa fonction moveBlockToPosition :
import { useDispatch } from '@wordpress/data';
const { moveBlockToPosition } = useDispatch( 'core/block-editor' );
moveBlockToPosition( clientId, fromRootClientId, toRootClientId, nouvelIndex );
Cette séparation entre affichage temporaire (l’indicateur de position) et action définitive (la mutation du magasin de données) explique pourquoi le glisser-déposer semble fluide : aucune structure de blocs n’est réellement modifiée tant que le geste est en cours, seul l’affichage change.
Pourquoi cette séparation compte pour un bloc composite
- Un bloc parent qui souhaite personnaliser l’ordre autorisé de ses enfants (via
InnerBlocks) ne doit pas intercepter les événements natifs du navigateur : il doit s’appuyer sur les mêmes fonctions du magasin de données que l’éditeur utilise en interne. - Le composant
Draggablereste un outil bas niveau : la plupart des blocs n’ont jamais besoin de l’utiliser directement, l’éditeur gérant déjà le glisser-déposer par défaut pour tout bloc enregistré normalement. - Un bloc qui refuse certaines réorganisations le fait via
templateLockouallowedBlocks, jamais en interceptant les événements de glisser eux-mêmes.
Un cas où comprendre ce mécanisme aide vraiment
Un bloc personnalisé qui affiche un aperçu complexe (une carte, un graphique) peut parfois capturer les événements de la souris avant qu’ils n’atteignent la poignée de déplacement de l’éditeur, rendant le bloc impossible à réordonner par glisser-déposer. Le diagnostic consiste alors à vérifier si un gestionnaire d’événement du bloc (souvent lié à une bibliothèque tierce comme une carte interactive) intercepte mousedown sur toute la surface du bloc, empêchant la poignée native de l’éditeur de fonctionner correctement.
Sur les blocs qui embarquent une bibliothèque tierce interactive (carte, graphique, éditeur riche), on isole systématiquement la zone interactive avec un conteneur dédié, pour laisser la poignée de déplacement de l’éditeur totalement libre en dehors de cette zone.
En résumé
Le glisser-déposer d’un bloc repose sur une séparation nette entre la capture du geste (via Draggable et les événements natifs du navigateur) et la mutation réelle de la structure (via le magasin de données core/block-editor). Cette architecture explique à la fois la fluidité perçue par le rédacteur et les rares cas où un bloc composite doit être conçu avec soin pour ne pas interférer avec ce mécanisme.