{% extends 'base.html.twig' %} {% block title %}Modal - Design System - Bubul{% endblock %} {% block body %}
{# ===== HEADER ===== #}
Molecules /

Modal

Dialogues modaux pour confirmations et formulaires

{# ===== COMPOSITION ===== #}

Composition

Overlay + Icon + Typography + Button = Modal
{# ===== CONTENU FLEXIBLE ===== #}

Que peut-on mettre dans un Modal ?

Le Modal utilise {% verbatim %}{% embed %}{% endverbatim %}, tu peux donc injecter n'importe quel contenu HTML dans le body.

{% verbatim %}{% block body %}{% endverbatim %}

  • - Formulaires complets
  • - Barre de recherche + resultats
  • - Listes d'utilisateurs
  • - Images, previews
  • - Tableaux de donnees
  • - Autres composants (Cards, Alerts...)

{% verbatim %}{% block footer %}{% endverbatim %}

  • - Boutons Annuler / Confirmer
  • - Bouton Submit de formulaire
  • - Liens d'action
  • - Checkbox "Ne plus afficher"
{# ===== VARIANTES ===== #}

Variantes predefinies

Parametre : variant - Configure automatiquement l'icone et les couleurs

{% include '_atoms/button/button.html.twig' with { label: 'Info', variant: 'outline', color: 'info', icon: 'info', attr: { onclick: "openModal('demo-info')" } } %} {% include '_atoms/button/button.html.twig' with { label: 'Success', variant: 'outline', color: 'success', icon: 'check-circle', attr: { onclick: "openModal('demo-success')" } } %} {% include '_atoms/button/button.html.twig' with { label: 'Warning', variant: 'outline', color: 'warning', icon: 'warning', attr: { onclick: "openModal('demo-warning')" } } %} {% include '_atoms/button/button.html.twig' with { label: 'Danger (Delete)', variant: 'outline', color: 'error', icon: 'trash', attr: { onclick: "openModal('demo-danger')" } } %}
{% verbatim %}{# Footer automatique avec actionLabel, actionIcon, cancelLabel #}
{% embed '_molecules/modal/modal.html.twig' with {
    id: 'delete-modal',
    title: 'Supprimer l element',
    subtitle: 'Cette action est irreversible',
    variant: 'danger',
    actionLabel: 'Supprimer',
    actionIcon: 'trash',
    cancelLabel: 'Annuler'
} %}
    {% block body %}...{% endblock %}
    {# Pas besoin de block footer ! #}
{% endembed %}{% endverbatim %}
{# ===== FORMULAIRES ===== #}

Avec formulaire

Le modal focus automatiquement le premier input a l'ouverture

{% include '_atoms/button/button.html.twig' with { label: 'Formulaire simple', variant: 'primary', icon: 'edit', attr: { onclick: "openModal('demo-form-simple')" } } %} {% include '_atoms/button/button.html.twig' with { label: 'Recherche utilisateurs', variant: 'outline', icon: 'search', attr: { onclick: "openModal('demo-search')" } } %} {% include '_atoms/button/button.html.twig' with { label: 'Formulaire complet', variant: 'outline', icon: 'user-add', attr: { onclick: "openModal('demo-form-full')" } } %}
{# ===== SIDE PANEL ===== #}

Side Panel

Parametre : position: right | left - Panel lateral au lieu de modal centre

{% include '_atoms/button/button.html.twig' with { label: 'Panel Droite', variant: 'primary', icon: 'chevron-right', attr: { onclick: "openModal('demo-panel-right')" } } %} {% include '_atoms/button/button.html.twig' with { label: 'Panel Gauche', variant: 'outline', icon: 'chevron-left', attr: { onclick: "openModal('demo-panel-left')" } } %} {% include '_atoms/button/button.html.twig' with { label: 'Panel Parametres', variant: 'ghost', icon: 'settings', attr: { onclick: "openModal('demo-panel-settings')" } } %}
{% verbatim %}{% embed '_molecules/modal/modal.html.twig' with {
    id: 'settings-panel',
    title: 'Parametres',
    icon: 'settings',
    position: 'right',
    size: 'md',
    actionLabel: 'Enregistrer',
    cancelLabel: 'Annuler'
} %}
    {% block body %}
        {# Contenu scrollable automatiquement #}
        ...
    {% endblock %}
{% endembed %}{% endverbatim %}

Note : En mode side-panel, le body est automatiquement scrollable et prend toute la hauteur disponible. Le footer reste fixe en bas.

{# ===== TAILLES ===== #}

Tailles

Parametre : size

{% include '_atoms/button/button.html.twig' with { label: 'Small (sm)', variant: 'ghost', size: 'sm', attr: { onclick: "openModal('demo-sm')" } } %} {% include '_atoms/button/button.html.twig' with { label: 'Medium (md)', variant: 'ghost', size: 'sm', attr: { onclick: "openModal('demo-md')" } } %} {% include '_atoms/button/button.html.twig' with { label: 'Large (lg)', variant: 'ghost', size: 'sm', attr: { onclick: "openModal('demo-lg')" } } %} {% include '_atoms/button/button.html.twig' with { label: 'XLarge (xl)', variant: 'ghost', size: 'sm', attr: { onclick: "openModal('demo-xl')" } } %} {% include '_atoms/button/button.html.twig' with { label: '2XLarge (2xl)', variant: 'ghost', size: 'sm', attr: { onclick: "openModal('demo-2xl')" } } %}
{# ===== PARAMETRES ===== #}

Parametres

Parametre Type Defaut Description
idstring(requis)ID unique pour open/close
titlestringnullTitre du modal
subtitlestringnullSous-titre / description
variantstringnullinfo, success, warning, danger (configure icone/couleurs)
iconstringautoIcone du header (auto si variant)
iconColorstringautoCouleur de l'icone (auto si variant)
sizestringmdsm, md, lg, xl, 2xl, full
positionstringcentercenter, right, left (side-panel)
closablebooltrueBouton fermeture X
closeOnOverlaybooltrueFermer au clic sur overlay
actionLabelstringnullFooter auto - Texte bouton action
actionIconstringnullFooter auto - Icone bouton action
actionUrlstringnullFooter auto - URL form (bouton type=submit)
cancelLabelstringnullFooter auto - Texte bouton annuler
classstring''Classes additionnelles
{# ===== FONCTIONS JS ===== #}

Fonctions JavaScript

// Ouvrir un modal
openModal('mon-modal-id');

// Fermer un modal
closeModal('mon-modal-id');

// Fermer avec la touche Escape (automatique)
{# =================================================================== MODALS DE DEMO - VARIANTES =================================================================== #} {# Info - avec footer automatique #} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-info', title: 'Information', subtitle: 'Voici quelques informations utiles', variant: 'info', actionLabel: 'Compris' } %} {% block body %}

Cette fonctionnalite vous permet de creer des cours automatiquement a partir de vos documents PDF.

Formats supportes : PDF, DOCX, TXT

{% endblock %} {% endembed %} {# Success - avec footer automatique #} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-success', title: 'Opération réussie', subtitle: 'Votre cours a été généré avec succès', variant: 'success', actionLabel: 'Voir le cours' } %} {% block body %}

Le cours "Introduction à la programmation" est maintenant disponible dans votre espace.

12 sections créées - 45 pages générées

{% endblock %} {% endembed %} {# Warning - avec footer automatique #} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-warning', title: 'Attention', subtitle: 'Votre quota de tokens est presque epuise', variant: 'warning', actionLabel: 'Recharger', cancelLabel: 'Plus tard' } %} {% block body %}

Il vous reste moins de 1000 tokens. Certaines fonctionnalites pourraient etre limitees.

{% include '_atoms/progress/progress.html.twig' with { value: 92, variant: 'warning', size: 'md' } %}

920 / 1000 tokens utilises

{% endblock %} {% endembed %} {# Danger / Delete - avec footer automatique et icone #} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-danger', title: 'Supprimer le cours', subtitle: 'Cette action est irreversible', variant: 'danger', actionLabel: 'Supprimer', actionIcon: 'trash', cancelLabel: 'Annuler' } %} {% block body %}

Êtes-vous sûr de vouloir supprimer le cours "Introduction à la programmation" ?

Toutes les données associées seront définitivement perdues.

{% endblock %} {% endembed %} {# =================================================================== MODALS DE DEMO - FORMULAIRES =================================================================== #} {# Formulaire simple #} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-form-simple', title: 'Renommer le cours', icon: 'edit', iconColor: 'primary' } %} {% block body %}
{% include '_molecules/form/form-field.html.twig' with { label: 'Nouveau nom', name: 'course_name', value: 'Introduction a la programmation', placeholder: 'Entrez le nouveau nom...' } %}
{% endblock %} {% block footer %} {% include '_atoms/button/button.html.twig' with { label: 'Annuler', variant: 'ghost', size: 'lg', class: 'mr-auto', attr: { onclick: "closeModal('demo-form-simple')" } } only %} {% include '_atoms/button/button.html.twig' with { label: 'Enregistrer', variant: 'primary', size: 'lg', attr: { onclick: "closeModal('demo-form-simple')" } } only %} {% endblock %} {% endembed %} {# Recherche utilisateurs #} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-search', title: 'Ajouter des participants', subtitle: 'Recherchez des utilisateurs a ajouter au cours', icon: 'users', iconColor: 'primary', size: 'lg' } %} {% block body %} {# Barre de recherche #}
{% include '_molecules/search-bar/search-bar.html.twig' with { placeholder: 'Rechercher un utilisateur...', size: 'md' } %}
{# Liste de resultats (simulee) #}
{% for user in [ { name: 'Jean Dupont', email: 'jean.dupont@email.com', selected: true }, { name: 'Marie Martin', email: 'marie.martin@email.com', selected: false }, { name: 'Pierre Durand', email: 'pierre.durand@email.com', selected: true }, { name: 'Sophie Bernard', email: 'sophie.bernard@email.com', selected: false }, { name: 'Lucas Petit', email: 'lucas.petit@email.com', selected: false } ] %} {% endfor %}

2 utilisateurs selectionnes

{% endblock %} {% block footer %} {% include '_atoms/button/button.html.twig' with { label: 'Annuler', variant: 'ghost', size: 'lg', class: 'mr-auto', attr: { onclick: "closeModal('demo-search')" } } only %} {% include '_atoms/button/button.html.twig' with { label: 'Ajouter (2)', variant: 'primary', size: 'lg', attr: { onclick: "closeModal('demo-search')" } } only %} {% endblock %} {% endembed %} {# Formulaire complet #} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-form-full', title: 'Nouvel utilisateur', subtitle: 'Ajoutez un utilisateur a votre organisation', icon: 'user-add', iconColor: 'primary', size: 'lg' } %} {% block body %}
{% include '_molecules/form/form-field.html.twig' with { label: 'Prenom', name: 'firstname', placeholder: 'Jean', required: true } %} {% include '_molecules/form/form-field.html.twig' with { label: 'Nom', name: 'lastname', placeholder: 'Dupont', required: true } %}
{% include '_molecules/form/form-field.html.twig' with { label: 'Email', name: 'email', type: 'email', placeholder: 'jean.dupont@email.com', required: true } %} {% include '_molecules/form/form-field.html.twig' with { label: 'Role', name: 'role', type: 'select', options: [ { value: 'user', label: 'Utilisateur' }, { value: 'admin', label: 'Administrateur' }, { value: 'teacher', label: 'Formateur' } ] } %} {% include '_atoms/form/checkbox.html.twig' with { name: 'send_invite', label: 'Envoyer une invitation par email', checked: true } %}
{% endblock %} {% block footer %} {% include '_atoms/button/button.html.twig' with { label: 'Annuler', variant: 'ghost', size: 'lg', class: 'mr-auto', attr: { onclick: "closeModal('demo-form-full')" } } only %} {% include '_atoms/button/button.html.twig' with { label: 'Creer l utilisateur', variant: 'primary', size: 'lg', attr: { onclick: "closeModal('demo-form-full')" } } only %} {% endblock %} {% endembed %} {# =================================================================== MODALS DE DEMO - TAILLES =================================================================== #} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-sm', title: 'Small Modal', size: 'sm' } %} {% block body %}

Modal de petite taille (max-w-sm). Ideal pour les confirmations simples.

{% endblock %} {% block footer %}{% include '_atoms/button/button.html.twig' with { label: 'Fermer', variant: 'primary', size: 'lg', attr: { onclick: "closeModal('demo-sm')" } } only %}{% endblock %} {% endembed %} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-md', title: 'Medium Modal', size: 'md' } %} {% block body %}

Modal de taille moyenne (max-w-md). Taille par defaut, convient a la plupart des cas.

{% endblock %} {% block footer %}{% include '_atoms/button/button.html.twig' with { label: 'Fermer', variant: 'primary', size: 'lg', attr: { onclick: "closeModal('demo-md')" } } only %}{% endblock %} {% endembed %} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-lg', title: 'Large Modal', size: 'lg' } %} {% block body %}

Modal de grande taille (max-w-lg). Pour les formulaires avec plusieurs champs.

{% endblock %} {% block footer %}{% include '_atoms/button/button.html.twig' with { label: 'Fermer', variant: 'primary', size: 'lg', attr: { onclick: "closeModal('demo-lg')" } } only %}{% endblock %} {% endembed %} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-xl', title: 'Extra Large Modal', size: 'xl' } %} {% block body %}

Modal extra large (max-w-xl). Pour les formulaires complexes ou affichage de donnees.

{% endblock %} {% block footer %}{% include '_atoms/button/button.html.twig' with { label: 'Fermer', variant: 'primary', size: 'lg', attr: { onclick: "closeModal('demo-xl')" } } only %}{% endblock %} {% endembed %} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-2xl', title: '2XL Modal', size: '2xl' } %} {% block body %}

Modal 2XL (max-w-2xl). Pour les tableaux de donnees ou previews larges.

{% endblock %} {% block footer %}{% include '_atoms/button/button.html.twig' with { label: 'Fermer', variant: 'primary', size: 'lg', attr: { onclick: "closeModal('demo-2xl')" } } only %}{% endblock %} {% endembed %} {# =================================================================== MODALS DE DEMO - SIDE PANELS =================================================================== #} {# Panel Droite #} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-panel-right', title: 'Panel Droite', subtitle: 'Panel lateral ancre a droite', icon: 'settings', iconColor: 'primary', position: 'right', size: 'md', actionLabel: 'Enregistrer', cancelLabel: 'Annuler' } %} {% block body %}

Ce panel est ancre a droite de l'ecran et prend toute la hauteur.

{% include '_molecules/form/form-field.html.twig' with { label: 'Nom du projet', name: 'project_name', placeholder: 'Mon projet...' } %} {% include '_molecules/form/form-field.html.twig' with { label: 'Description', name: 'description', type: 'textarea', rows: 4, placeholder: 'Description du projet...' } %}

Options

{% include '_atoms/form/checkbox.html.twig' with { name: 'opt1', label: 'Option 1' } %} {% include '_atoms/form/checkbox.html.twig' with { name: 'opt2', label: 'Option 2', checked: true } %} {% include '_atoms/form/checkbox.html.twig' with { name: 'opt3', label: 'Option 3' } %}
{% endblock %} {% endembed %} {# Panel Gauche #} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-panel-left', title: 'Navigation', icon: 'list', iconColor: 'primary', position: 'left', size: 'sm' } %} {% block body %} {% endblock %} {% block footer %} {% include '_atoms/button/button.html.twig' with { label: 'Fermer', variant: 'ghost', size: 'lg', fullWidth: true, attr: { onclick: "closeModal('demo-panel-left')" } } only %} {% endblock %} {% endembed %} {# Panel Parametres complet #} {% embed '_molecules/modal/modal.html.twig' with { id: 'demo-panel-settings', title: 'Parametres de l activite', subtitle: 'Configurez les options de cette activite', icon: 'settings', iconColor: 'primary', position: 'right', size: 'lg', actionLabel: 'Appliquer', cancelLabel: 'Annuler' } %} {% block body %}
{# Section 1 #}

Informations generales

{% include '_molecules/form/form-field.html.twig' with { label: 'Titre', name: 'title', value: 'Introduction au cours' } %} {% include '_molecules/form/form-field.html.twig' with { label: 'Duree estimee', name: 'duration', value: '15 minutes', hint: 'Temps moyen pour completer cette activite' } %}

{# Section 2 #}

Options d affichage

{% include '_atoms/form/checkbox.html.twig' with { name: 'show_nav', label: 'Afficher la navigation', checked: true } %} {% include '_atoms/form/checkbox.html.twig' with { name: 'show_progress', label: 'Afficher la progression', checked: true } %} {% include '_atoms/form/checkbox.html.twig' with { name: 'allow_skip', label: 'Autoriser a passer' } %}

{# Section 3 #}

Contenu additionnel

Ajoutez du contenu supplementaire visible en bas de l'activite.

{% include '_molecules/form/form-field.html.twig' with { label: 'Notes pour l apprenant', name: 'notes', type: 'textarea', rows: 3, placeholder: 'Conseils, ressources complementaires...' } %}
{% endblock %} {% endembed %} {% endblock %}