{# # ============================================================================ # ORGANISM: CONTEXT BANNER # ============================================================================ # # Bandeau contextuel pleine largeur, collé en haut d'une section. # Affiche le contexte actif (ex: entreprise sélectionnée) avec un # sélecteur optionnel pour changer de contexte. # # Conçu pour s'échapper du padding de la
grâce aux classes # -mx-6 lg:-mx-8 -mt-8 lg:-mt-12. À placer en tout premier enfant du body. # # ============================================================================ # COMPOSITION (Atomes utilisés) # ============================================================================ # # - _atoms/icon/icon.html.twig # # ============================================================================ # PARAMÈTRES # ============================================================================ # # | Paramètre | Type | Défaut | Description | # |-------------|--------|------------|-----------------------------------------| # | title | string | (requis) | Titre du contexte (ex: nom entreprise) | # | subtitle | string | null | Sous-titre optionnel (HTML autorisé) | # | icon | string | 'building' | Icône gauche (Solar icon) | # | color | string | 'primary' | Accent couleur: primary, cohorts, | # | | | | success, warning | # | theme | string | 'light' | 'light' = fond blanc (recommandé) | # | | | | 'dark' = fond coloré plein | # | selector | object | null | Config du sélecteur de contexte | # | | | | { items: [{label, value}], selected, | # | | | | controller, baseUrl } | # | actions | array | null | Boutons [{label, href, icon}] | # | sticky | bool | true | Sticky top-0 au scroll | # | class | string | '' | Classes Tailwind additionnelles | # # ============================================================================ # EXEMPLES D'UTILISATION # ============================================================================ # # Thème clair (recommandé): # {% include '_organisms/context-banner/context-banner.html.twig' with { # title: company.name, # subtitle: '12 apprenants · 4 cours', # icon: 'building', # color: 'cohorts', # theme: 'light', # selector: { # items: companies|map(c => { label: c.name, value: c.uuid }), # selected: company.uuid, # controller: 'sam--company-selector', # baseUrl: app.request.pathinfo # } # } %} # # Thème sombre (fond coloré): # {% include '_organisms/context-banner/context-banner.html.twig' with { # title: 'Acme Corp', # icon: 'building', # color: 'cohorts', # theme: 'dark' # } %} # # ============================================================================ #} {# ============================================================================ CONFIGURATION DES VALEURS PAR DÉFAUT ============================================================================ #} {% set title = title ?? 'Contexte' %} {% set subtitle = subtitle ?? null %} {% set icon = icon ?? 'building' %} {% set color = color ?? 'primary' %} {% set theme = theme ?? 'light' %} {% set selector = selector ?? null %} {% set actions = actions ?? null %} {% set sticky = sticky ?? true %} {% set escape = escape ?? true %} {% set class = class ?? '' %} {# ============================================================================ MAP DES STYLES PAR COULEUR × THÈME ============================================================================ #} {% set styleMap = { 'light': { 'primary': { 'wrapper': 'bg-white shadow-sm border-b border-gray-200', 'topBorder': 'bg-primary', 'iconBg': 'bg-primary/10', 'iconColor': 'primary', 'title': 'text-gray-900', 'subtitle': 'text-gray-500', 'selectWrap': 'bg-white border border-gray-200 text-gray-700 hover:border-primary focus-within:border-primary focus-within:ring-1 focus-within:ring-primary/20', 'chevron': 'gray', 'actionClass': 'bg-primary/8 text-primary hover:bg-primary/15' }, 'cohorts': { 'wrapper': 'bg-white shadow-sm border-b border-gray-200', 'topBorder': 'bg-cohorts', 'iconBg': 'bg-cohorts/10', 'iconColor': 'cohorts', 'title': 'text-gray-900', 'subtitle': 'text-gray-500', 'selectWrap': 'bg-white border border-gray-200 text-gray-700 hover:border-cohorts focus-within:border-cohorts focus-within:ring-1 focus-within:ring-cohorts/20', 'chevron': 'gray', 'actionClass': 'bg-cohorts/8 text-cohorts hover:bg-cohorts/15' }, 'success': { 'wrapper': 'bg-white shadow-sm border-b border-gray-200', 'topBorder': 'bg-success', 'iconBg': 'bg-success/10', 'iconColor': 'success', 'title': 'text-gray-900', 'subtitle': 'text-gray-500', 'selectWrap': 'bg-white border border-gray-200 text-gray-700 hover:border-success focus-within:border-success', 'chevron': 'gray', 'actionClass': 'bg-success/8 text-success hover:bg-success/15' }, 'warning': { 'wrapper': 'bg-white shadow-sm border-b border-gray-200', 'topBorder': 'bg-warning', 'iconBg': 'bg-warning/10', 'iconColor': 'warning', 'title': 'text-gray-900', 'subtitle': 'text-gray-500', 'selectWrap': 'bg-white border border-gray-200 text-gray-700 hover:border-warning focus-within:border-warning', 'chevron': 'gray', 'actionClass': 'bg-warning/8 text-warning hover:bg-warning/15' } }, 'dark': { 'primary': { 'wrapper': 'bg-primary shadow-primary border-b border-primary-dark/30', 'topBorder': null, 'iconBg': 'bg-white/15', 'iconColor': 'white', 'title': 'text-white', 'subtitle': 'text-white/70', 'selectWrap': 'bg-primary-dark/40 border border-white/20 text-white', 'chevron': 'white', 'actionClass': 'bg-white/10 text-white hover:bg-white/20' }, 'cohorts': { 'wrapper': 'bg-cohorts shadow-cohorts border-b border-cohorts-dark/30', 'topBorder': null, 'iconBg': 'bg-white/15', 'iconColor': 'white', 'title': 'text-white', 'subtitle': 'text-white/70', 'selectWrap': 'bg-cohorts-dark/40 border border-white/20 text-white', 'chevron': 'white', 'actionClass': 'bg-white/10 text-white hover:bg-white/20' }, 'success': { 'wrapper': 'bg-success shadow-md border-b border-success-dark/30', 'topBorder': null, 'iconBg': 'bg-white/15', 'iconColor': 'white', 'title': 'text-white', 'subtitle': 'text-white/70', 'selectWrap': 'bg-success-dark/40 border border-white/20 text-white', 'chevron': 'white', 'actionClass': 'bg-white/10 text-white hover:bg-white/20' }, 'warning': { 'wrapper': 'bg-warning shadow-md border-b border-warning-dark/30', 'topBorder': null, 'iconBg': 'bg-white/15', 'iconColor': 'white', 'title': 'text-white', 'subtitle': 'text-white/70', 'selectWrap': 'bg-warning-dark/40 border border-white/20 text-white', 'chevron': 'white', 'actionClass': 'bg-white/10 text-white hover:bg-white/20' } } } %} {% set s = styleMap[theme][color] ?? styleMap['light']['primary'] %} {# ============================================================================ RENDU HTML ============================================================================ #}
{# Trait de couleur en haut (thème light uniquement) #} {% if s.topBorder %}
{% endif %}
{# ── Gauche : icône + titre + sous-titre ── #}
{% include '_atoms/icon/icon.html.twig' with { name: icon, size: 'md', color: s.iconColor } only %}

{{ title }}

{% if subtitle %}

{{ subtitle|raw }}

{% endif %}
{# ── Droite : sélecteur et/ou actions ── #}
{# Sélecteur de contexte (affiché si > 1 item) #} {% if selector and selector.items|length > 1 %}
{% include '_atoms/icon/icon.html.twig' with { name: 'chevron-down', size: 'xs', color: s.chevron } only %}
{% endif %} {# Actions optionnelles #} {% if actions %} {% for action in actions %} {% if action.icon is defined %} {% include '_atoms/icon/icon.html.twig' with { name: action.icon, size: 'xs', color: (theme == 'light') ? color : 'white' } only %} {% endif %} {{ action.label }} {% endfor %} {% endif %}