{# # ============================================================================ # ATOM: BADGE # ============================================================================ # # Badge paramétrable utilisant 100% Tailwind CSS. # Les couleurs sont définies dans: assets/styles/variables.css # # ============================================================================ # PARAMÈTRES # ============================================================================ # # | Paramètre | Type | Défaut | Description | # |-----------|---------|-----------|------------------------------------------| # | label | string | '' | Texte du badge | # | variant | string | 'neutral' | Style: primary, success, warning, error, | # | | | | info, neutral, dark, white | # | size | string | 'md' | Taille: xs, sm, md, lg | # | dot | bool | false | Afficher un point de statut | # | pulse | bool | false | Animer le dot (ping) — nécessite dot:true | # | dotVariant | string | null | Override couleur dot (ex: 'success') | # | icon | string | null | Nom de l'icône (ex: 'check', 'alert') | # | count | number | null | Compteur optionnel | # | outline | bool | false | Version outline (bordure sans fond) | # | rounded | string | 'full' | Arrondi: sm, md, lg, full | # | preset | string | null | Preset prédéfini (voir liste ci-dessous) | # | customColor | string | null | Couleur hex dynamique (ex: '#0C81E4') | # | | | | Override variant: bg 6%, border 16% | # | class | string | '' | Classes Tailwind additionnelles | # # ============================================================================ # PRESETS DISPONIBLES # ============================================================================ # # | Preset | Label | Variant | Dot | Usage | # |---------------------|------------|---------|-------|----------------------| # | contract-active | Actif | success | true | Contrat actif | # | contract-expired | Expiré | error | true | Contrat expiré | # | contract-upcoming | À venir | info | true | Contrat à venir | # | contract-disabled | Désactivé | neutral | false | Contrat désactivé | # | user-active | Actif | success | true | Utilisateur actif | # | user-inactive | Inactif | neutral | false | Utilisateur inactif | # | user-pending | En attente | warning | true | Utilisateur en attente| # | company-active | Active | success | true | Entreprise active | # | company-inactive | Inactive | neutral | false | Entreprise inactive | # # ============================================================================ # EXEMPLES D'UTILISATION # ============================================================================ # # Badge simple: # {% include '_atoms/badge/badge.html.twig' with { label: 'Nouveau' } %} # # Badge avec variante: # {% include '_atoms/badge/badge.html.twig' with { # label: 'Actif', # variant: 'success', # dot: true # } %} # # Badge avec preset (recommandé): # {% include '_atoms/badge/badge.html.twig' with { # preset: 'contract-active', # size: 'sm' # } %} # # Badge avec icône: # {% include '_atoms/badge/badge.html.twig' with { # label: 'Validé', # variant: 'success', # icon: 'check' # } %} # # Badge compteur: # {% include '_atoms/badge/badge.html.twig' with { # label: 'Messages', # count: 5, # variant: 'primary' # } %} # # ============================================================================ #} {# ============================================================================ PRESETS PRÉDÉFINIS Centralise les configurations réutilisables pour éviter la duplication ============================================================================ #} {% set presets = { 'contract-active': { label: 'Actif', variant: 'success', dot: true }, 'contract-expired': { label: 'Expiré', variant: 'error', dot: true }, 'contract-upcoming': { label: 'À venir', variant: 'info', dot: true }, 'contract-disabled': { label: 'Désactivé', variant: 'neutral', dot: false }, 'user-active': { label: 'Actif', variant: 'success', dot: true }, 'user-inactive': { label: 'Inactif', variant: 'error', dot: true }, 'user-pending': { label: 'En attente', variant: 'warning', dot: true }, 'company-active': { label: 'Active', variant: 'success', dot: true }, 'company-inactive': { label: 'Inactive', variant: 'neutral', dot: false } } %} {# ============================================================================ CONFIGURATION DES VALEURS PAR DÉFAUT ============================================================================ #} {% set preset = preset ?? null %} {% set presetConfig = preset ? (presets[preset] ?? null) : null %} {% set label = label ?? (presetConfig ? presetConfig.label : '') %} {% set variant = variant ?? (presetConfig ? presetConfig.variant : 'neutral') %} {% set dot = dot ?? (presetConfig ? presetConfig.dot : false) %} {% set size = size ?? 'md' %} {% set icon = icon ?? null %} {% set count = count ?? null %} {% set pulse = pulse ?? false %} {% set dotVariant = dotVariant ?? null %} {% set outline = outline ?? false %} {% set rounded = rounded ?? 'full' %} {% set customColor = customColor ?? null %} {% set class = class ?? '' %} {# ============================================================================ CLASSES TAILWIND - BASE ============================================================================ #} {% set baseClasses = 'inline-flex items-center font-medium whitespace-nowrap select-none' %} {# ============================================================================ CLASSES TAILWIND - TAILLES ============================================================================ #} {% set sizeClasses = { 'xs': 'h-5 px-2 text-xs gap-1', 'sm': 'h-6 px-2.5 text-xs gap-1.5', 'md': 'h-7 px-3 text-sm gap-1.5', 'lg': 'h-8 px-4 text-sm gap-2', 'count': 'h-5 min-w-[1.25rem] px-1.5 text-xs' } %} {# ============================================================================ CLASSES TAILWIND - VARIANTES (fond léger) ============================================================================ #} {% set variantClasses = { 'primary': 'bg-primary/10 text-primary', 'success': 'bg-success/10 text-success', 'warning': 'bg-warning/10 text-warning', 'error': 'bg-error/10 text-error', 'info': 'bg-info/10 text-info', 'cohorts': 'bg-cohorts/10 text-cohorts', 'neutral': 'bg-gray-100 text-gray-600', 'dark': 'bg-gray-800 text-white', 'white': 'bg-white text-gray-700 border border-gray-200 shadow-sm', 'count': 'bg-primary text-white font-bold justify-center' } %} {# ============================================================================ CLASSES TAILWIND - VARIANTES OUTLINE ============================================================================ #} {% set outlineClasses = { 'primary': 'bg-transparent text-primary border border-primary/30', 'success': 'bg-transparent text-success border border-success/30', 'warning': 'bg-transparent text-warning border border-warning/30', 'error': 'bg-transparent text-error border border-error/30', 'info': 'bg-transparent text-info border border-info/30', 'cohorts': 'bg-transparent text-cohorts border border-cohorts/30', 'neutral': 'bg-transparent text-gray-600 border border-gray-300', 'dark': 'bg-transparent text-gray-800 border border-gray-800' } %} {# ============================================================================ CLASSES TAILWIND - ROUNDED ============================================================================ #} {% set roundedClasses = { 'sm': 'rounded-sm', 'md': 'rounded-md', 'lg': 'rounded-lg', 'full': 'rounded-full' } %} {# ============================================================================ TAILLES D'ICÔNES ET DOTS ============================================================================ #} {% set iconSizes = { 'xs': 'xs', 'sm': 'xs', 'md': 'sm', 'lg': 'sm' } %} {% set dotSizes = { 'xs': 'w-1.5 h-1.5', 'sm': 'w-1.5 h-1.5', 'md': 'w-2 h-2', 'lg': 'w-2.5 h-2.5' } %} {# ============================================================================ COULEURS DES DOTS ============================================================================ #} {% set dotColors = { 'primary': 'bg-primary', 'success': 'bg-success', 'warning': 'bg-warning', 'error': 'bg-error', 'info': 'bg-info', 'cohorts': 'bg-cohorts', 'neutral': 'bg-gray-400', 'dark': 'bg-white', 'white': 'bg-gray-400' } %} {# ============================================================================ ASSEMBLAGE DES CLASSES ============================================================================ #} {% set badgeClasses = [ baseClasses, sizeClasses[size] ?? sizeClasses['md'], outline ? (outlineClasses[variant] ?? outlineClasses['neutral']) : (variantClasses[variant] ?? variantClasses['neutral']), roundedClasses[rounded] ?? roundedClasses['full'], class ]|join(' ')|trim %} {# ============================================================================ RENDU HTML ============================================================================ #} {# ----- Dot de statut ----- #} {% if dot %} {% if pulse %} {% endif %} {% endif %} {# ----- Icône ----- #} {% if icon and not dot %} {% include '_atoms/icon/icon.html.twig' with { name: icon, size: iconSizes[size] ?? 'sm', class: 'shrink-0' } only %} {% endif %} {# ----- Label ----- #} {% if label %} {{ label }} {% endif %} {# ----- Compteur ----- #} {% if count is not null %} {{ count }} {% endif %}