{# # ============================================================================ # MOLECULE: MODAL # ============================================================================ # # Dialogue modal avec overlay, header, body et footer. # Utilise pour confirmations, formulaires et affichage de contenu. # Supporte aussi le mode side-panel (position: right/left). # # ============================================================================ # COMPOSITION (Atomes utilises) # ============================================================================ # # - _atoms/icon/icon.html.twig # - _atoms/typography/typography.html.twig # - _atoms/button/button.html.twig # # ============================================================================ # PARAMETRES # ============================================================================ # # | Parametre | Type | Defaut | Description | # |---------------|---------|-----------|------------------------------------------| # | id | string | (requis) | ID unique pour le modal | # | title | string | null | Titre du modal | # | subtitle | string | null | Sous-titre/description | # | variant | string | null | Preset: info, success, warning, danger | # | icon | string | null | Icone du header (auto si variant) | # | iconColor | string | 'primary' | Couleur de l'icone (auto si variant) | # | size | string | 'md' | Taille: sm, md, lg, xl, 2xl, full | # | position | string | 'center' | Position: center, right, left (panel) | # | closable | bool | true | Afficher bouton fermeture | # | closeOnOverlay| bool | true | Fermer au clic sur overlay | # | actionLabel | string | null | Texte bouton action (genere footer auto) | # | actionIcon | string | null | Icone bouton action | # | actionUrl | string | null | URL action (form action ou href) | # | actionMethod | string | 'POST' | Methode HTTP pour actionUrl | # | cancelLabel | string | null | Texte bouton annuler (si actionLabel) | # | class | string | '' | Classes additionnelles | # # ============================================================================ # VARIANTES PREDEFINES # ============================================================================ # # | Variant | Icone | Couleur | Usage | # |---------|--------------|---------|------------------------------------------| # | info | info | info | Information, aide | # | success | check-circle | success | Confirmation de succes | # | warning | warning | warning | Avertissement, attention | # | danger | trash | error | Suppression, action irreversible | # # ============================================================================ # EXEMPLES D'UTILISATION # ============================================================================ # # Modal de confirmation (recommande): # {% embed '_molecules/modal/modal.html.twig' with { # id: 'delete-modal', # title: 'Supprimer l element', # variant: 'danger', # actionLabel: 'Supprimer', # actionIcon: 'trash', # cancelLabel: 'Annuler' # } %} # {% block body %} #
Cette action est irreversible.
# {% endblock %} # {% endembed %} # # Side-panel (position: right): # {% embed '_molecules/modal/modal.html.twig' with { # id: 'settings-panel', # title: 'Parametres', # icon: 'settings', # position: 'right', # size: 'md' # } %} # {% block body %} # # {% endblock %} # {% block footer %} # {% include '_atoms/button/button.html.twig' with { label: 'Enregistrer' } %} # {% endblock %} # {% endembed %} # # Modal avec formulaire et action URL: # {% embed '_molecules/modal/modal.html.twig' with { # id: 'form-modal', # title: 'Ajouter un utilisateur', # size: 'lg', # actionLabel: 'Ajouter', # actionUrl: '/admin/users/create', # cancelLabel: 'Annuler' # } %} # {% block body %} # # {% endblock %} # {% endembed %} # # ============================================================================ #} {# ============================================================================ CONFIGURATION DES VALEURS PAR DEFAUT ============================================================================ #} {% set id = id ?? 'modal' %} {% set title = title ?? null %} {% set subtitle = subtitle ?? null %} {% set variant = variant ?? null %} {% set size = size ?? 'md' %} {% set position = position ?? 'center' %} {% set closable = closable ?? true %} {% set closeOnOverlay = closeOnOverlay ?? true %} {% set actionLabel = actionLabel ?? null %} {% set actionIcon = actionIcon ?? null %} {% set actionUrl = actionUrl ?? null %} {% set actionMethod = actionMethod ?? 'POST' %} {% set cancelLabel = cancelLabel ?? null %} {% set class = class ?? '' %} {# Mode side-panel #} {% set isSidePanel = position in ['right', 'left'] %} {# ============================================================================ CONFIGURATION DES VARIANTES ============================================================================ #} {% set variantConfig = { 'info': { 'icon': 'info', 'iconColor': 'info', 'iconBg': 'bg-info/10', 'headerBorder': 'border-info/20', 'buttonVariant': 'primary' }, 'success': { 'icon': 'check-circle', 'iconColor': 'success', 'iconBg': 'bg-success/10', 'headerBorder': 'border-success/20', 'buttonVariant': 'success' }, 'warning': { 'icon': 'warning', 'iconColor': 'warning', 'iconBg': 'bg-warning/10', 'headerBorder': 'border-warning/20', 'buttonVariant': 'warning' }, 'danger': { 'icon': 'trash', 'iconColor': 'error', 'iconBg': 'bg-error/10', 'headerBorder': 'border-error/20', 'buttonVariant': 'error' } } %} {% set vConfig = variant ? (variantConfig[variant] ?? null) : null %} {# Appliquer la config de variante ou utiliser les valeurs manuelles #} {% set icon = icon ?? (vConfig ? vConfig.icon : null) %} {% set iconColor = iconColor ?? (vConfig ? vConfig.iconColor : 'primary') %} {% set iconBg = vConfig ? vConfig.iconBg : ('bg-' ~ iconColor ~ '/10') %} {# ============================================================================ CLASSES TAILWIND ============================================================================ #} {# Classes de taille selon le mode #} {% if isSidePanel %} {% set sizeClasses = { 'sm': 'w-80', 'md': 'w-96', 'lg': 'w-[28rem]', 'xl': 'w-[32rem]', '2xl': 'w-[40rem]', 'full': 'w-full' } %} {% else %} {% set sizeClasses = { 'sm': 'max-w-sm', 'md': 'max-w-md', 'lg': 'max-w-lg', 'xl': 'max-w-xl', '2xl': 'max-w-2xl', 'full': 'max-w-full mx-4' } %} {% endif %} {# Classes du modal/panel #} {% if isSidePanel %} {% set positionClasses = position == 'right' ? 'right-0' : 'left-0' %} {% set modalClasses = [ 'h-full bg-white shadow-xl overflow-hidden flex flex-col', sizeClasses[size] ?? sizeClasses['md'], positionClasses, class ]|join(' ')|trim %} {% else %} {% set modalClasses = [ 'w-full bg-white rounded-xl shadow-xl overflow-hidden', sizeClasses[size] ?? sizeClasses['md'], class ]|join(' ')|trim %} {% endif %} {# ============================================================================ RENDU HTML ============================================================================ #} {# Overlay + Container #}