{# Composants UI normalisés (charte « Accessible chaleureux »). Usage dans une page : {% from "components/ui.html" import button, card, badge, alert %} {{ button("Enregistrer", variant="primary") }} {% call card() %} ... {% endcall %} Toutes les classes dérivent des tokens de la charte (static/src/input.css). #} {# Bouton ou lien stylé. variant : primary | secondary | ghost. Passe href pour un lien , sinon un {%- endif -%} {% endmacro %} {# Carte de contenu. Utiliser avec {% call card() %} ... {% endcall %}. #} {% macro card(extra="") %}
{{ caller() }}
{% endmacro %} {# Pastille / étiquette courte. tone : teal | success | warning | danger | neutral. #} {% macro badge(label, tone="teal") %} {%- set tones = { "teal": "text-teal bg-teal-soft", "success": "text-teal bg-teal-soft", "warning": "text-ocre bg-orange-50", "danger": "text-red-700 bg-red-50", "neutral": "text-subtle bg-cream" } -%} {{ label }} {% endmacro %} {# Message contextuel. level : success | error | warning | info. #} {% macro alert(message, level="info") %} {%- set tones = { "success": "bg-teal-soft text-teal border-teal-border", "error": "bg-red-50 text-red-700 border-red-200", "warning": "bg-orange-50 text-ocre border-ocre/30", "info": "bg-cream text-subtle border-line" } -%}
{{ message }}
{% endmacro %} {# Rendu d'un message flash de session. flash : dict {message, level} ou None. La page passe flash en contexte (ex. via un context provider applicatif). #} {% macro flash_messages(flash) %} {% if flash %}
{{ alert(flash.message, level=flash.level | default("info")) }}
{% endif %} {% endmacro %} {# En-tête de page : titre, sous-titre optionnel, bouton d'action optionnel. #} {% macro page_header(title, subtitle="", action_label="", action_href="") %}

{{ title }}

{% if subtitle %}

{{ subtitle }}

{% endif %}
{% if action_label and action_href %}{{ button(action_label, variant="primary", href=action_href) }}{% endif %}
{% endmacro %} {# Bloc « aucune donnée » pour une liste vide. #} {% macro empty_state(message, hint="") %}

{{ message }}

{% if hint %}

{{ hint }}

{% endif %}
{% endmacro %} {# Chiffre-clé. #} {% macro stat(value, label) %}
{{ value }}
{{ label }}
{% endmacro %} {# Fil d'Ariane. items : liste de couples (libellé, href). Le dernier item (href vide ou None) est la page courante, non cliquable. #} {% macro breadcrumb(items) %} {% endmacro %} {# Barre de navigation. links : liste de couples (libellé, href). current : href de la page active (surlignée). À placer dans le bloc nav du layout. #} {% macro navbar(links, current="") %} {% for label, href in links %} {{ label }} {% endfor %} {% endmacro %}