# Antipatterns : cinq blocs qui réimplémentent chacun leur propre fenêtre modale

> Ce qu'on observe en revue de code quand chaque bloc d'une extension gère sa propre fenêtre modale, pourquoi cela pèse sur la cohérence, et comment mutualiser.

- Auteur : Clément Hadrot
- Publié le : 2025-11-06
- Mis à jour le : 2025-11-06
- Catégorie : Blocs Gutenberg
- URL : https://wpmoderne.dev.wordpress-developpement.fr/blocs/antipatterns-cinq-blocs-reimplementent-fenetre-modale/

## L’essentiel

- Cinq implémentations de modale, cinq comportements clavier différents
- Le poids du bundle grandit sans apporter de fonctionnalité nouvelle
- Un seul composant partagé règle la cohérence et le poids en même temps

Cinq blocs, cinq fenêtres modales, cinq comportements légèrement différents au clavier : c'est ce que révèle une revue de code sur une extension qui a grandi bloc après bloc, sans jamais revenir sur les fondations communes. Ce billet ne tranche pas le choix technique entre l'élément HTML `dialog` et un composant `Modal` de bibliothèque : il documente ce qu'on observe, pourquoi c'est un problème, et comment mutualiser sans tout réécrire d'un coup.

Le contexte est fréquent : un bloc « galerie » ouvre une image en grand dans une superposition, un bloc « témoignages » ouvre une vidéo, un bloc « fiche produit » ouvre un formulaire de contact, chacun développé à des périodes différentes du projet, par des mains différentes.

## Ce qu'on voit en revue de code

Chaque bloc contient sa propre gestion d'ouverture et de fermeture, souvent un état booléen local géré par `useState`, une superposition en position fixe, et un gestionnaire de clic sur l'arrière-plan pour fermer la fenêtre. Cinq fichiers différents, cinq variantes du même problème :

- Un seul des cinq blocs referme la fenêtre modale avec la touche Échap.
- Deux blocs sur cinq ramènent le focus clavier sur l'élément qui a ouvert la fenêtre après sa fermeture, les trois autres l'abandonnent au corps de la page.
- Aucun des cinq ne piège le focus à l'intérieur de la fenêtre pendant qu'elle est ouverte, ce qui laisse un utilisateur au clavier tabuler vers le contenu masqué en arrière-plan.

## Pourquoi c'est un problème de cohérence et de poids

Le premier coût est immédiatement visible pour l'utilisateur : une même action, « fermer une fenêtre superposée », se comporte différemment selon le bloc concerné. Un visiteur qui a appris que la touche Échap fonctionne sur le bloc galerie s'attend, à raison, à ce qu'elle fonctionne aussi sur le bloc fiche produit.

> L'essentiel à retenir : Cinq implémentations de modale, cinq comportements clavier différents ; Le poids du bundle grandit sans apporter de fonctionnalité nouvelle ; Un seul composant partagé règle la cohérence et le poids en même temps

Le second coût, moins visible mais tout aussi réel, concerne le poids du code livré. Cinq implémentations quasi identiques de la logique d'ouverture, de fermeture et de gestion du focus alourdissent le bundle JavaScript sans ajouter la moindre fonctionnalité perceptible par l'utilisateur final. Ce poids s'additionne à chaque nouveau bloc qui reproduit le même schéma plutôt que de réutiliser une base commune.

### Un troisième coût, plus discret : la maintenance

Corriger un bug d'accessibilité sur la gestion du focus, découvert sur un bloc, ne corrige rien sur les quatre autres. Chaque correctif doit être reporté manuellement, multiplié par le nombre d'implémentations, avec un risque réel d'oubli sur l'une d'entre elles.

## Comment mutualiser sans tout réécrire d'un coup

La mutualisation ne demande pas de refondre les cinq blocs en une seule session. Elle commence par l'extraction d'un composant partagé, placé dans un dossier commun de l'extension, qui gère uniquement l'ouverture, la fermeture, le piégeage du focus et la fermeture au clavier, sans connaître le contenu affiché à l'intérieur :

```
function FenetreSuperposee( { ouverte, onFermer, children } ) {
	if ( ! ouverte ) {
		return null;
	}
	return (
		<div role="dialog" aria-modal="true" onKeyDown={ gererClavier }>
			{ children }
		</div>
	);
}
```

Chaque bloc peut ensuite migrer vers ce composant partagé à son propre rythme, un bloc à la fois, sans bloquer les autres chantiers en cours.

### Prioriser la migration selon l'usage réel

Sur un projet où les cinq blocs n'ont pas la même fréquence d'utilisation, il est raisonnable de migrer d'abord le bloc le plus consulté par les visiteurs, celui dont une régression d'accessibilité aurait le plus d'impact, plutôt que de suivre l'ordre chronologique de création des blocs.

> Un conseil qui revient souvent en revue de code : dès qu'un deuxième bloc a besoin d'une fenêtre superposée, c'est le bon moment pour extraire un composant partagé, avant qu'un troisième, un quatrième et un cinquième ne viennent ancrer l'antipattern.

## En résumé

Cinq blocs qui réimplémentent chacun leur propre fenêtre modale ne sont pas seulement un problème esthétique de duplication : ils produisent une expérience incohérente pour l'utilisateur, un bundle plus lourd que nécessaire, et une maintenance multipliée par le nombre d'implémentations. L'extraction d'un composant partagé, migré bloc par bloc, résout les trois problèmes en même temps sans exiger une réécriture globale immédiate.
