# Ranger les réglages d’un bloc complexe dans des panneaux dépliables

> Au-delà d'une dizaine de réglages, un inspecteur de bloc devient illisible. PanelBody structure ces contrôles en sections dépliables, sans changer la logique de l'éditeur.

- Auteur : WordPress Développement
- Publié le : 2023-11-29
- Mis à jour le : 2026-09-30
- Catégorie : Blocs Gutenberg
- URL : https://www.wpmoderne.fr/blocs/panneaux-depliables-inspectorcontrols-reglages-bloc/

## L’essentiel

- PanelBody regroupe des contrôles sous un intitulé dépliable
- initialOpen évite d'ouvrir tous les panneaux à la fois
- Plusieurs PanelBody peuvent cohabiter dans un même InspectorControls

Un inspecteur de bloc qui empile quinze contrôles à la suite, sans structure visible, devient rapidement plus difficile à parcourir qu'à utiliser : le rédacteur doit faire défiler l'ensemble pour retrouver un seul réglage, même familier. Passé une dizaine de contrôles, ranger l'inspecteur en sections dépliables change concrètement l'expérience d'édition, sans toucher à la logique métier du bloc.

## Le composant PanelBody, brique de base du rangement

Fourni par `@wordpress/components`, `PanelBody` enveloppe un groupe de contrôles sous un intitulé cliquable, qui se replie et se déplie indépendamment des autres panneaux du même inspecteur. Plusieurs instances de `PanelBody` peuvent cohabiter dans un même `InspectorControls`, chacune correspondant à une catégorie logique de réglages : apparence, comportement, accessibilité, données liées.

## Mise en place étape par étape

> L'essentiel à retenir : PanelBody regroupe des contrôles sous un intitulé dépliable ; initialOpen évite d'ouvrir tous les panneaux à la fois ; Plusieurs PanelBody peuvent cohabiter dans un même InspectorControls

1. Identifier les groupes logiques de réglages du bloc (au moins deux ou trois catégories distinctes justifient l'usage de panneaux séparés).
2. Importer `PanelBody` depuis `@wordpress/components`, en plus des contrôles déjà utilisés.
3. Envelopper chaque groupe de contrôles dans son propre `PanelBody`, avec un `title` explicite.
4. Décider, panneau par panneau, si `initialOpen` doit valoir `true` (pour les réglages les plus fréquemment consultés) ou `false`.
5. Vérifier dans l'éditeur que l'ouverture d'un panneau ne referme pas les autres involontairement (ce n'est normalement pas le comportement par défaut).

Prenons un bloc « Carte de tarif » dont l'inspecteur accumule les réglages : contenu, mise en avant, apparence. Voici d'abord les attributs déclarés dans `block.json` :

```
{
	"apiVersion": 3,
	"name": "tarifs/carte",
	"title": "Carte de tarif",
	"category": "widgets",
	"attributes": {
		"titre": { "type": "string", "default": "" },
		"prix": { "type": "string", "default": "" },
		"periode": { "type": "string", "default": "mois" },
		"mettreEnAvant": { "type": "boolean", "default": false },
		"libelleBadge": { "type": "string", "default": "Recommandé" },
		"rayon": { "type": "number", "default": 8 }
	},
	"editorScript": "file:./index.js"
}
```

Et voici la fonction d'édition, avec trois panneaux : le premier, ouvert au chargement, contient les réglages de contenu ; les deux autres sont repliés.

```
import { __ } from '@wordpress/i18n';
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import {
	PanelBody,
	TextControl,
	ToggleControl,
	SelectControl,
	RangeControl,
} from '@wordpress/components';

export default function Edit( { attributes, setAttributes } ) {
	const { titre, prix, periode, mettreEnAvant, libelleBadge, rayon } = attributes;
	const blockProps = useBlockProps( { style: { borderRadius: rayon } } );

	return (
		<>
			<InspectorControls>
				<PanelBody title={ __( 'Contenu', 'tarifs' ) } initialOpen={ true }>
					<TextControl
						label={ __( 'Titre', 'tarifs' ) }
						value={ titre }
						onChange={ ( valeur ) => setAttributes( { titre: valeur } ) }
					/>
					<TextControl
						label={ __( 'Prix', 'tarifs' ) }
						value={ prix }
						onChange={ ( valeur ) => setAttributes( { prix: valeur } ) }
					/>
					<SelectControl
						label={ __( 'Période', 'tarifs' ) }
						value={ periode }
						options={ [
							{ label: __( 'Par mois', 'tarifs' ), value: 'mois' },
							{ label: __( 'Par an', 'tarifs' ), value: 'an' },
						] }
						onChange={ ( valeur ) => setAttributes( { periode: valeur } ) }
					/>
				</PanelBody>

				<PanelBody title={ __( 'Mise en avant', 'tarifs' ) } initialOpen={ false }>
					<ToggleControl
						label={ __( 'Afficher un badge', 'tarifs' ) }
						checked={ mettreEnAvant }
						onChange={ ( valeur ) => setAttributes( { mettreEnAvant: valeur } ) }
					/>
					{ mettreEnAvant && (
						<TextControl
							label={ __( 'Texte du badge', 'tarifs' ) }
							value={ libelleBadge }
							onChange={ ( valeur ) => setAttributes( { libelleBadge: valeur } ) }
						/>
					) }
				</PanelBody>

				<PanelBody title={ __( 'Apparence', 'tarifs' ) } initialOpen={ false }>
					<RangeControl
						label={ __( 'Arrondi des angles', 'tarifs' ) }
						value={ rayon }
						min={ 0 }
						max={ 32 }
						onChange={ ( valeur ) => setAttributes( { rayon: valeur } ) }
					/>
				</PanelBody>
			</InspectorControls>

			<div { ...blockProps }>
				<strong>{ titre }</strong> { prix }
			</div>
		</>
	);
}
```

Le découpage suit la logique de l'usage, pas celle du code : ce que le rédacteur modifie à chaque fois (titre, prix) est dans le panneau ouvert ; ce qu'il règle une fois pour toutes (angles arrondis) est dans un panneau replié. Le panneau « Mise en avant » ne montre le champ du badge que si l'option est activée, ce qui évite d'afficher un réglage sans effet.

## Un seul panneau ouvert à la fois

Par défaut, les panneaux sont indépendants : en ouvrir un ne referme pas les autres. Si votre inspecteur compte beaucoup de sections, on peut obtenir un comportement d'accordéon en pilotant l'état soi-même. La propriété `opened` rend le panneau contrôlé, et `onToggle` est appelée à chaque clic sur son intitulé :

```
import { useState } from '@wordpress/element';

const [ panneauOuvert, setPanneauOuvert ] = useState( 'contenu' );

const basculer = ( identifiant ) => () =>
	setPanneauOuvert( panneauOuvert === identifiant ? null : identifiant );

// ...
<PanelBody
	title={ __( 'Apparence', 'tarifs' ) }
	opened={ panneauOuvert === 'apparence' }
	onToggle={ basculer( 'apparence' ) }
>
	{ /* contrôles */ }
</PanelBody>
```

Ce code remplace `initialOpen` : dès qu'un panneau reçoit `opened`, il est entièrement piloté par votre état, et `initialOpen` n'a plus d'objet. L'appel à `useState()` se place en tête de la fonction d'édition, avant le `return`. Cet accordéon n'est pas toujours souhaitable : un rédacteur qui compare deux réglages situés dans deux panneaux doit pouvoir garder les deux ouverts.

## Choisir ce qui s'ouvre et dans quel ordre

- Ouvrez au chargement un seul panneau, celui des réglages les plus fréquents ; laisser les autres repliés donne un inspecteur lisible dès la sélection du bloc.
- Placez les panneaux dans l'ordre d'usage : contenu, puis comportement, puis apparence, puis réglages avancés.
- Donnez à chaque panneau un intitulé qui décrit ce qu'il contient, pas une catégorie vague comme « Options » ou « Divers ».
- Ne créez pas de panneau pour un contrôle isolé : un panneau de deux ou trois contrôles au minimum a du sens.

## Pièges courants

- **Un panneau vide.** Si tous ses contrôles sont conditionnels, le panneau reste affiché avec son intitulé et rien dedans. Rendez plutôt conditionnel le `PanelBody` entier.
- **Des `PanelBody` imbriqués.** Ils produisent une interface déroutante et n'apportent rien que deux panneaux côte à côte ne donnent déjà.
- **Un intitulé non traduit.** Le `title` passe par `__()` comme n'importe quelle chaîne visible.
- **Les panneaux hors de `InspectorControls`.** Hors de ce composant, ils s'affichent dans le canevas de l'éditeur, et non dans la barre latérale.
- **Les onglets de l'inspecteur.** Dans les versions récentes de WordPress, l'inspecteur propose des onglets Réglages et Styles ; `InspectorControls` accepte alors une propriété `group` pour placer un panneau d'apparence dans l'onglet des styles. Vérifiez la prise en charge dans la version minimale que vous visez.

> Un inspecteur bien rangé ne montre pas tous les réglages : il montre les bons au bon moment, et laisse les autres à un clic.

## Conclusion

`PanelBody` est un composant modeste qui change beaucoup l'expérience d'un bloc complexe : les réglages sont regroupés par intention, l'ouverture initiale oriente le regard, et rien dans la logique du bloc ne change puisque les attributs restent les mêmes. Commencez par regrouper vos contrôles en deux ou trois panneaux, laissez ouvert celui du quotidien, et testez l'inspecteur avec quelqu'un qui n'a pas conçu le bloc : c'est la meilleure mesure de sa lisibilité.
