Composants
Les composants se rendent avec la syntaxe Symfony UX Twig Component :
La documentation référence les composants Twig à utiliser directement. Évitez les include de templates internes : les sous-composants publics couvrent les cas de composition maintenables.
<twig:dsfr:button label="Enregistrer" />
Passez les tableaux avec la syntaxe Twig : :
<twig:dsfr:breadcrumb :items="[
{label: 'Accueil', href: '/'},
{label: 'Dossier', current: true}
]" />
Les composants composables utilisent leurs sous-composants. N'utilisez pas de blocs Twig nommés comme footer, rows, panels, image ou options : ces slots ne font pas partie de l'API publique.
Catalogue détaillé
La section Catalogue des composants contient une page par composant DSFR disponible dans le bundle, avec les composants Twig à utiliser, un exemple, les règles d’usage importantes et un tableau de configuration.
Règles d'intégration
- Utilisez uniquement les composants Twig UX publics : pas de macro, pas d'include de template interne.
- Passez les collections avec
:pour conserver les tableaux PHP/Twig. - Les composants composables se construisent avec leurs sous-composants : carte, modale, tableau, onglets, en-tête, pied de page et navigation.
- Les attributs HTML non consommés sont transmis au nœud racine quand le template le permet ; utilisez-les pour
data-*,aria-*,classetidspécifiques à votre application. - Gardez les libellés accessibles explicites :
ariaLabel,label,title,caption,legendet alternatives d'image ne doivent pas être vides quand ils portent l'information.
Community
Ces composants sont utilisables sans licence Pro :
dsfr:buttondsfr:linkdsfr:tagdsfr:badgedsfr:alertdsfr:highlightdsfr:breadcrumbdsfr:paginationdsfr:stepperdsfr:skip:linksdsfr:containerdsfr:grid:rowdsfr:grid:col
Exemples rapides
Boutons
<twig:dsfr:button label="Primaire" />
<twig:dsfr:button label="Secondaire" variant="secondary" />
<twig:dsfr:button label="Lien" href="/tableau-de-bord" />
<twig:dsfr:button label="Ajouter" icon="fr-icon-add-line" />
<twig:dsfr:button label="Favori" icon="fr-icon-star-line" iconOnly />
Un bouton avec href rend un lien <a class="fr-btn">. Sans href, il rend un <button type="button">.
Groupes de boutons
<twig:dsfr:button:group inline iconPlace="left">
<twig:dsfr:button label="Enregistrer" icon="fr-icon-save-line" />
<twig:dsfr:button label="Annuler" variant="secondary" />
</twig:dsfr:button:group>
Quand des boutons avec icône sont dans un groupe DSFR, définissez iconPlace sur le groupe pour conserver le libellé visible.
Feedback
<twig:dsfr:alert title="Succès" text="La demande est enregistrée." type="success" />
<twig:dsfr:badge label="Nouveau" type="new" />
<twig:dsfr:highlight text="Information importante." accent="blue-cumulus" />
Navigation
<twig:dsfr:pagination currentPage="2" totalPages="8" urlPattern="/page/%d" />
<twig:dsfr:stepper title="Informations" currentStep="2" stepCount="4" nextStep="Validation" />
Choisir un composant
| Besoin développeur | Composant à utiliser |
|---|---|
| Structurer une page ou un dashboard | dsfr:container, dsfr:grid:row, dsfr:grid:col |
| Déclencher une action | dsfr:button ou dsfr:button:group |
| Naviguer vers une page | dsfr:link, dsfr:breadcrumb, dsfr:pagination, dsfr:nav |
| Afficher un statut | dsfr:badge, dsfr:alert, dsfr:notice |
| Collecter une saisie | dsfr:input, dsfr:select, dsfr:checkbox, dsfr:radio, dsfr:toggle |
| Montrer un contenu riche | dsfr:card, dsfr:tile, dsfr:table, dsfr:tabs, dsfr:accordion |
| Ouvrir une surcouche | dsfr:modal avec dsfr:modal:title, content et footer |
| Gérer un consentement | dsfr:consent et dsfr:consent:placeholder |
Support rapide
| Problème courant | Vérification |
|---|---|
| Un composant Pro ne s'affiche pas en production | Vérifiez la licence avec php bin/console dsfr:license:validate. |
| Un menu, une modale ou un accordéon ne s'ouvre pas | Vérifiez que le JavaScript DSFR est chargé et que id, aria-controls et les cibles existent. |
| Les props tableau ne sont pas lues | Utilisez le préfixe Twig : : :items="[]", :links="[]", :options="[]". |
| Une option booléenne ne produit rien | Utilisez dismissible, expanded, checked ou disabled sans valeur, ou passez une vraie valeur booléenne. |
| Le rendu casse la mise en page | Commencez par dsfr:container, puis dsfr:grid:row gutters, puis des colonnes responsives. |
| Une erreur d'accessibilité apparaît dans le profiler | Corrigez d'abord les titres, caption, legend, alternatives d'image et relations aria-*. |
Pro
Les composants non listés dans la section Community sont en Pro. En environnement local, ils restent visibles pour développer. En production, une licence valide est requise.
Composition recommandée
<twig:dsfr:modal id="example-modal">
<twig:dsfr:modal:content>
<twig:dsfr:modal:title modalId="example-modal">Confirmer l'action</twig:dsfr:modal:title>
<p>Le contenu de la modale reste dans le composant de contenu.</p>
</twig:dsfr:modal:content>
<twig:dsfr:modal:footer>
<twig:dsfr:button label="Confirmer" type="button" />
<twig:dsfr:button label="Annuler" variant="secondary" type="button" />
</twig:dsfr:modal:footer>
</twig:dsfr:modal>
<twig:dsfr:table id="agents-table" caption="Agents" bordered>
<twig:dsfr:table:head>
<twig:dsfr:table:row>
<twig:dsfr:table:head:cell>Nom</twig:dsfr:table:head:cell>
<twig:dsfr:table:head:cell>Statut</twig:dsfr:table:head:cell>
</twig:dsfr:table:row>
</twig:dsfr:table:head>
<twig:dsfr:table:body>
<twig:dsfr:table:row>
<twig:dsfr:table:cell>Alice Martin</twig:dsfr:table:cell>
<twig:dsfr:table:cell>Actif</twig:dsfr:table:cell>
</twig:dsfr:table:row>
</twig:dsfr:table:body>
</twig:dsfr:table>
Catalogue DSFR
| DSFR | Composant Twig |
|---|---|
| Accordéon | dsfr:accordion, dsfr:accordion:group |
| Ajout de fichier | dsfr:upload |
| Alerte | dsfr:alert |
| Badge | dsfr:badge, dsfr:badge:group |
| Bandeau d'information importante | dsfr:notice |
| Barre de recherche | dsfr:search:bar |
| Bloc marque | dsfr:logo |
| Bouton | dsfr:button, dsfr:button:group |
| Bouton FranceConnect | dsfr:france:connect |
| Bouton radio | dsfr:radio |
| Carte | dsfr:card, dsfr:card:header, dsfr:card:body, dsfr:card:content, dsfr:card:title, dsfr:card:description, dsfr:card:footer |
| Case à cocher | dsfr:checkbox |
| Champ de saisie | dsfr:input, dsfr:textarea |
| Citation | dsfr:quote |
| Contenu médias | dsfr:media:content |
| Contrôle segmenté | dsfr:segmented |
| Curseur | dsfr:range |
| En-tête | dsfr:header, dsfr:header:brand, dsfr:header:tools |
| Fil d'Ariane | dsfr:breadcrumb, dsfr:breadcrumb:item |
| Formulaire | Types Symfony Dsfr*Type et thème @Dsfr/form/dsfr_form_theme.html.twig |
| Gestionnaire de consentement | dsfr:consent, dsfr:consent:placeholder |
| Grille et conteneur | dsfr:container, dsfr:grid:row, dsfr:grid:col |
| Indicateur d’étapes | dsfr:stepper |
| Infobulle | dsfr:tooltip |
| Interrupteur | dsfr:toggle, dsfr:toggle:group |
| Lettre d'information et réseaux sociaux | dsfr:follow |
| Lien | dsfr:link, dsfr:links:group |
| Liens d'évitement | dsfr:skip:links |
| Liste déroulante | dsfr:select |
| Liste déroulante riche | dsfr:combobox |
| Menu déroulant | dsfr:dropdown |
| Menu latéral | dsfr:sidemenu |
| Mise en avant | dsfr:callout |
| Mise en exergue | dsfr:highlight |
| Modale | dsfr:modal, dsfr:modal:title, dsfr:modal:content, dsfr:modal:footer |
| Mot de passe | dsfr:password |
| Navigation principale | dsfr:nav, dsfr:nav:item, dsfr:nav:menu, dsfr:nav:mega |
| Navigation tertiaire | dsfr:tabnav |
| Onglet | dsfr:tabs, dsfr:tabs:list, dsfr:tabs:tab, dsfr:tabs:panel |
| Pagination | dsfr:pagination |
| Paramètres d'affichage | dsfr:display |
| Partage | dsfr:share |
| Pied de page | dsfr:footer, dsfr:footer:top, dsfr:footer:brand, dsfr:footer:content, dsfr:footer:partners, dsfr:footer:bottom |
| Sélecteur de langues | dsfr:translate |
| Sommaire | dsfr:summary |
| Tableau | dsfr:table, dsfr:table:head, dsfr:table:body, dsfr:table:row, dsfr:table:cell, dsfr:table:head:cell |
| Tag | dsfr:tag, dsfr:tag:group |
| Téléchargement de fichier | dsfr:download |
| Transcription | dsfr:transcription |
| Tuile | dsfr:tile |
| Zone d’expression visuelle | dsfr:composition |
Exemples utiles
<twig:dsfr:container>
<twig:dsfr:grid:row gutters>
<twig:dsfr:grid:col cols="12" md="6">Colonne gauche</twig:dsfr:grid:col>
<twig:dsfr:grid:col cols="12" md="6">Colonne droite</twig:dsfr:grid:col>
</twig:dsfr:grid:row>
</twig:dsfr:container>
<twig:dsfr:upload id="document" label="Ajouter un justificatif" name="document" />
<twig:dsfr:password id="password" label="Mot de passe" name="password" />
<twig:dsfr:range id="progress" label="Avancement" min="0" max="100" value="40" />
<twig:dsfr:segmented id="period" legend="Période" name="period" :options="[
{value: 'day', label: 'Jour', checked: true},
{value: 'week', label: 'Semaine'}
]" />
<twig:dsfr:sidemenu title="Documentation" :items="[
{label: 'Composants', href: '/docs/components', active: true}
]" />
<twig:dsfr:summary :links="[
{label: 'Installation', href: '#installation'}
]" />
<twig:dsfr:download title="Télécharger le dossier" href="/files/dossier.pdf" detail="PDF - 240 Ko" />