Aller au contenu

Composant · Structure

PanelSection

Stable

Une section d'un PanelStack : un en-tête (titre, contrôles optionnels) et un corps. C'est la brique d'un panneau latéral découpé en régions — filtres, détails, conversation. Le corps reste monté en permanence : le repli est purement CSS, si bien qu'un contenu à état (carte, éditeur, session de chat) survit à un repli/dépli sans être remonté.

À utiliser dans un PanelStack

PanelSection est conçu pour vivre dans un PanelStack, qui décide seul de la forme (shape), de la section dépliée et de l'unique section propriétaire du défilement. Sans stack ancêtre, une section se replie sur un comportement sain — dépliée, propriétaire du défilement, non primaire — mais elle perd toute coordination avec ses voisines.

Forme « sticky-item »

Forme par défaut : une seule section dépliée à la fois, tous les en-têtes restant visibles. Chaque en-tête replié est un bouton de divulgation (aria-expanded / aria-controls) qui étiquette sa région.

Panneau latéral à trois sections

La section ouverte possède le défilement ; les autres restent réduites à leur en-tête.

Période : 30 derniers jours.

Statut : en cours.

Métadonnées de l'élément.

Douze événements.

Voir le code (Svelte)
<div style="block-size:20rem;inline-size:min(100%, 26rem);border:1px solid var(--st-semantic-border-subtle);border-radius:0.5rem;padding:0 0.5rem;overflow:hidden">
  <PanelStack label="Panneau latéral" defaultExpanded="filters">
    <PanelSection id="filters" label="Filtres">
      <p style="margin:0 0 0.75rem;font-size:0.875rem">La section ouverte possède le défilement ; les autres restent réduites à leur en-tête.</p>
      <p style="margin:0 0 0.75rem;font-size:0.875rem">Période : 30 derniers jours.</p>
      <p style="margin:0 0 0.75rem;font-size:0.875rem">Statut : en cours.</p>
    </PanelSection>
    <PanelSection id="details" label="Détails">
      <p style="margin:0 0 0.75rem;font-size:0.875rem">Métadonnées de l'élément.</p>
    </PanelSection>
    <PanelSection id="history" label="Historique">
      <p style="margin:0 0 0.75rem;font-size:0.875rem">Douze événements.</p>
    </PanelSection>
  </PanelStack>
</div>

Forme « split-primary »

Une section primaire est toujours dépliée et possède le défilement ; les autres sont des divulgations dimensionnées par leur contenu. La primaire n'affiche volontairement pas de bouton : elle ne peut pas se replier, une affordance de repli mentirait. Elle conserve un plancher utile (primaryMinHeight, 160 px par défaut) : sous ce seuil, c'est une secondaire qui se replie plutôt que la primaire qui s'écrase.

Conversation primaire + annexes

Section primaire : toujours dépliée, sans affordance de repli, propriétaire du défilement.

Message 1

Message 2

Message 3

Trois documents cités.

Modèle, température.

Voir le code (Svelte)
<div style="block-size:20rem;inline-size:min(100%, 26rem);border:1px solid var(--st-semantic-border-subtle);border-radius:0.5rem;padding:0 0.5rem;overflow:hidden">
  <PanelStack shape="split-primary" label="Panneau d'assistance" primary="chat">
    <PanelSection id="chat" label="Conversation">
      <p style="margin:0 0 0.75rem;font-size:0.875rem">Section primaire : toujours dépliée, sans affordance de repli, propriétaire du défilement.</p>
      <p style="margin:0 0 0.75rem;font-size:0.875rem">Message 1</p>
      <p style="margin:0 0 0.75rem;font-size:0.875rem">Message 2</p>
      <p style="margin:0 0 0.75rem;font-size:0.875rem">Message 3</p>
    </PanelSection>
    <PanelSection id="sources" label="Sources">
      <p style="margin:0 0 0.75rem;font-size:0.875rem">Trois documents cités.</p>
    </PanelSection>
    <PanelSection id="settings" label="Réglages">
      <p style="margin:0 0 0.75rem;font-size:0.875rem">Modèle, température.</p>
    </PanelSection>
  </PanelStack>
</div>

Au plus quatre sections par stack (PANEL_STACK_MAX_SECTIONS) : au-delà, empiler des régions repliables dans un panneau rend le défilement ingérable. Le dépassement est signalé par un avertissement en développement, jamais par une troncature silencieuse.

API du composant

PropTypeDéfautDescription
idstringrequisIdentifiant de la section : c'est par lui que le stack la désigne (expanded, primary).
labelstringrequisTitre affiché dans l'en-tête.
childrenSnippet—Contenu du corps de la section.
actionsSnippet—Contrôles en fin d'en-tête (boutons, compteurs).
classstring—Classe CSS supplémentaire sur la racine.

React, Vue et Angular exposent la même API ; en Angular, actions est un booléen qui active le slot (slot="actions"), faute de pouvoir détecter du contenu projeté optionnel.

Le parent : PanelStack

PropTypeDéfautDescription
shape'sticky-item' | 'split-primary''sticky-item'Règle de coordination des sections.
labelstring—Nom accessible de la région du stack.
expanded / defaultExpandedstring | null—sticky-item : id de la section dépliée, contrôlé ou en graine.
onExpandedChange(id: string | null) => void—Notification de changement.
primarystring—split-primary : id de la section propriétaire du défilement.
primaryMinHeightnumber160Plancher utile de la primaire, en px.

Angular — limite connue. Déclarez les PanelSection directement dans le template du PanelStack. Des sections produites par @for, ou des sections statiques mêlées à des sections sous @if / @for, reçoivent l'état du stack trop tard : en mode développement, Angular lève NG0100 (ExpressionChangedAfterItHasBeenChecked) ; en production, la première image montre ces sections avec leurs défauts hors stack (dépliées, chacune propriétaire du défilement), et dans une application sans zone.js elles restent ainsi tant que rien ne les fait revérifier (une interaction, par exemple). Limite non corrigée à ce jour.

Tokens CSS

Variable CSSDescription
--st-component-accordion-paddingBlock / -paddingInlineRembourrage de l'en-tête.
--st-component-accordion-fontSize / -fontWeight / -lineHeight / -textTypographie du titre de section.
--st-component-control-hoverBackgroundSurvol de l'en-tête repliable.
--st-component-control-borderSéparateur entre deux sections.
--st-component-panelStack-primaryMinBlockSizePlancher CSS de la section propriétaire du défilement, émis par PanelStack depuis primaryMinHeight.
--st-semantic-border-focusAnneau de focus de l'en-tête. Point de surcharge uniquement : aucun thème ne le définit, le composant retombe sur --st-semantic-brand-default tant que vous ne lui donnez pas de valeur.