{# # ============================================================================ # MOLECULE: FILTER TABS # ============================================================================ # # Groupe de boutons filtres style Moodia. # Conteneur pill avec fond blanc et filtres arrondis. # # ============================================================================ # COMPOSITION (Atomes utilisés) # ============================================================================ # # - Aucun (composant autonome) # # ============================================================================ # PARAMÈTRES # ============================================================================ # # | Paramètre | Type | Défaut | Description | # |---------------|---------|-----------|-----------------------------------| # | filters | array | (requis) | Liste des filtres | # | └ id | string | (requis) | Identifiant du filtre | # | └ label | string | (requis) | Texte du filtre | # | └ count | number | null | Compteur | # | └ href | string | null | URL (si lien au lieu de bouton) | # | └ icon | string | null | Nom d'icône (atome icon) | # | └ attr | object | {} | Attributs HTML additionnels | # | active | string | premier | ID du filtre actif | # | size | string | 'md' | sm, md, lg | # | name | string | 'filter' | Nom pour le data-attribute | # | clientToggle | bool | false | État actif basculé par le JS (.active) | # | class | string | '' | Classes additionnelles | # # ============================================================================ # EXEMPLES D'UTILISATION # ============================================================================ # # Filtres de type: # {% include '_molecules/filter-tabs/filter-tabs.html.twig' with { # filters: [ # { id: 'all', label: 'Tous', count: 40 }, # { id: 'course', label: 'Cours', count: 10 }, # { id: 'course_quiz', label: 'Cours + Quiz', count: 29 }, # { id: 'quiz_only', label: 'Quiz', count: 1 } # ], # active: 'all' # } %} # # ============================================================================ #} {# ============================================================================ CONFIGURATION DES VALEURS PAR DÉFAUT ============================================================================ #} {% set filters = filters ?? [] %} {% set active = active ?? (filters|first).id ?? null %} {% set size = size ?? 'md' %} {% set name = name ?? 'filter' %} {% set class = class ?? '' %} {# `clientToggle` : l'état actif est basculé par le JS après le rendu. Les styles passent alors en variantes `[&.active]:` pour que le script n'ait qu'UNE classe à ajouter ou retirer — lui faire manipuler la liste complète des classes du bouton actif le rendrait solidaire du détail visuel de cette molécule. #} {% set clientToggle = clientToggle ?? false %} {# ============================================================================ CLASSES TAILWIND ============================================================================ #} {% set sizeConfig = { 'sm': { 'padding': 'px-3 py-1.5', 'text': 'text-xs', 'gap': 'gap-1.5', 'containerPadding': 'p-1', 'containerGap': 'gap-1', 'countPadding': 'px-1.5 py-0.5', 'countText': 'text-[10px]' }, 'md': { 'padding': 'px-4 py-2.5', 'text': 'text-sm', 'gap': 'gap-2', 'containerPadding': 'p-1.5', 'containerGap': 'gap-1.5', 'countPadding': 'px-2 py-0.5', 'countText': 'text-[11px]' }, 'lg': { 'padding': 'px-5 py-3', 'text': 'text-base', 'gap': 'gap-2.5', 'containerPadding': 'p-2', 'containerGap': 'gap-2', 'countPadding': 'px-2.5 py-1', 'countText': 'text-xs' } } %} {% set sConfig = sizeConfig[size] ?? sizeConfig['md'] %} {# ============================================================================ RENDU HTML ============================================================================ #}