{# # ============================================================================ # MOLECULE: CHART CARD # ============================================================================ # # Carte enveloppant un graphique : en-tête (pastille d'icône, titre, # sous-titre), bloc d'actions à droite, corps portant le canvas et l'état vide. # # Elle ne dessine rien elle-même : le rendu est le travail d'un contrôleur # Stimulus, branché par le paramètre `attr`. La molécule ne connaît donc ni # Chart.js ni le domaine — seulement la boîte. # # ============================================================================ # COMPOSITION (Atomes utilisés) # ============================================================================ # # - icon (pastille d'en-tête et état vide) # # ============================================================================ # PARAMÈTRES # ============================================================================ # # | Paramètre | Type | Défaut | Description | # |-------------|---------|---------------|--------------------------------------| # | title | string | 'Graphique' | Titre de la carte | # | subtitle | string | null | Ligne de contexte sous le titre | # | icon | string | null | Nom d'icône de la pastille | # | iconColor | string | 'primary' | primary, info, success, warning, | # | | | | error, cohorts | # | height | string | 'md' | sm, md, lg (hauteur de la zone) | # | emptyText | string | 'Aucune…' | Texte de l'état vide | # | emptyIcon | string | 'chart' | Icône de l'état vide | # | attr | object | {} | Attributs HTML du conteneur | # | class | string | '' | Classes additionnelles | # # Blocs (via {% embed %}) : actions, body, aside # # ============================================================================ # EXEMPLES D'UTILISATION # ============================================================================ # # {% embed '_molecules/chart-card/chart-card.html.twig' with { # title: 'Commissions', subtitle: 'Douze mois', icon: 'chart', # attr: { 'data-controller': 'shared--trend-chart' } # } only %} # {% block actions %}…pastilles de période…{% endblock %} # {% endembed %} # # ============================================================================ #} {# ============================================================================ CONFIGURATION DES VALEURS PAR DÉFAUT ============================================================================ #} {% set title = title ?? 'Graphique' %} {% set subtitle = subtitle ?? null %} {% set icon = icon ?? null %} {% set iconColor = iconColor ?? 'primary' %} {% set height = height ?? 'md' %} {% set emptyText = emptyText ?? 'Aucune donnée' %} {% set emptyIcon = emptyIcon ?? 'chart' %} {% set attr = attr ?? {} %} {% set class = class ?? '' %} {# ============================================================================ CLASSES TAILWIND Classes complètes dans chaque branche : une classe construite dynamiquement (`bg-{{ iconColor }}/10`) serait purgée au build. ============================================================================ #} {% set bgMap = { 'primary': 'bg-primary/10', 'info': 'bg-info/10', 'success': 'bg-success/10', 'warning': 'bg-warning/10', 'error': 'bg-error/10', 'cohorts': 'bg-cohorts/10' } %} {% set heightMap = { 'sm': 'h-40', 'md': 'h-56', 'lg': 'h-72' } %} {% set iconBg = bgMap[iconColor] ?? bgMap['primary'] %} {% set zoneHeight = heightMap[height] ?? heightMap['md'] %} {# ============================================================================ RENDU HTML ============================================================================ #}
{% if icon %}
{% include '_atoms/icon/icon.html.twig' with { name: icon, size: 'xs', color: iconColor } only %}
{% endif %}

{{ title }}

{% if subtitle %}

{{ subtitle }}

{% endif %}
{% block actions %}{% endblock %}
{% block body %}
{# Révélé par le contrôleur quand la série est vide. Rendu masqué : sans données, un canvas vide ne dit rien, et sans JS la carte reste muette plutôt que d'annoncer à tort une absence. #}
{% endblock %} {% block aside %}{% endblock %}