Le WordPress d'aujourd'hui, décodé pour les développeurs

Blocs Gutenberg

Draggable et le glisser-déposer d’un bloc : ce qui se joue en coulisses

Réordonner deux blocs d'un glisser-déposer semble instantané. Derrière ce geste simple, plusieurs composants coopèrent pour recalculer la position sans jamais toucher au DOM directement.

Par WordPress Développement • 7 octobre 2021 • 4 min de lecture • Aucun commentaire
Draggable et le glisser-déposer d'un bloc : ce qui se joue en coulisses

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

L'essentiel à retenir : Le composant Draggable gère la capture du geste, pas le positionnement final ; Le calcul de la nouvelle position passe par le magasin de données, pas par le DOM ; Un indicateur visuel distinct signale la position d'insertion prévue

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 Draggable reste 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 templateLock ou allowedBlocks, 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.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi