{# # ============================================================================ # MOLECULE: NAV ITEM # ============================================================================ # # Élément de navigation pour sidebar ou menu. # Supporte les icônes, badges, et états actif/collapsed. # # ============================================================================ # COMPOSITION (Atomes utilisés) # ============================================================================ # # - _atoms/icon/icon.html.twig # - _atoms/badge/badge.html.twig # # ============================================================================ # PARAMÈTRES # ============================================================================ # # | Paramètre | Type | Défaut | Description | # |---------------|---------|-----------|-----------------------------------| # | label | string | (requis) | Texte du lien | # | href | string | '#' | URL de destination | # | icon | string | null | Nom de l'icône | # | badge | string | null | Texte du badge (compteur) | # | newLabel | string | 'NEW' | Libellé du badge nouveauté (isNew) | # | proBadge | bool | false | Affiche un badge « PRO » (prioritaire sur isNew) | # | active | bool | false | État actif | # | collapsed | bool | false | Mode collapsed (icône seule) | # | locked | bool | false | Affiche un cadenas rouge | # | variant | string | 'default' | default, primary, minimal | # | colorScheme | string | 'blue' | Palette de couleurs : blue, violet | # | toolColorHex | string | null | Couleur primaire hex depuis la DB (#RRGGBB) — colore l'icône + état actif | # | toolColorSecondary | string | null | Couleur secondaire hex depuis la DB (#RRGGBB) — couche fond de l'icône | # | toolColorBg | string | null | Couleur fond hex depuis la DB (#RRGGBB) — fond état actif | # | size | string | 'md' | sm, md, lg | # | external | bool | false | Lien externe (nouvelle fenêtre) | # | disabled | bool | false | État désactivé | # | class | string | '' | Classes additionnelles | # # ============================================================================ # EXEMPLES D'UTILISATION # ============================================================================ # # Navigation simple: # {% include '_molecules/nav-item/nav-item.html.twig' with { # label: 'Dashboard', # icon: 'home', # href: '/dashboard' # } %} # # Item actif avec badge: # {% include '_molecules/nav-item/nav-item.html.twig' with { # label: 'Messages', # icon: 'mail', # href: '/messages', # active: true, # badge: '5' # } %} # # Mode collapsed: # {% include '_molecules/nav-item/nav-item.html.twig' with { # label: 'Settings', # icon: 'settings', # href: '/settings', # collapsed: true # } %} # # ============================================================================ #} {# ============================================================================ CONFIGURATION DES VALEURS PAR DÉFAUT ============================================================================ #} {% set label = label ?? 'Navigation' %} {% set href = href ?? '#' %} {% set icon = icon ?? null %} {% set badge = badge ?? null %} {% set badgeVariant = badgeVariant ?? null %} {% set active = active ?? false %} {% set collapsed = collapsed ?? false %} {% set locked = locked ?? false %} {% set variant = variant ?? 'default' %} {% set colorScheme = colorScheme ?? 'blue' %} {% set toolColorHex = toolColorHex ?? null %} {% set toolColorSecondary = toolColorSecondary ?? null %} {% set toolColorBg = toolColorBg ?? null %} {% set size = size ?? 'md' %} {% set external = external ?? false %} {% set disabled = disabled ?? false %} {% set class = class ?? '' %} {% set turboDisabled = turboDisabled ?? false %} {% set isNew = isNew ?? false %} {% set newLabel = newLabel ?? 'NEW' %} {% set proBadge = proBadge ?? false %} {# ============================================================================ CLASSES TAILWIND ============================================================================ #} {% set sizeConfig = { 'sm': { 'padding': 'px-3 py-3', 'paddingCollapsed': 'p-3', 'text': 'text-sm', 'iconSize': 'sm', 'gap': 'gap-3', 'rounded': 'rounded-xl' }, 'md': { 'padding': 'px-4 py-3.5', 'paddingCollapsed': 'p-3', 'text': 'text-sm', 'iconSize': 'md', 'gap': 'gap-3', 'rounded': 'rounded-xl' }, 'lg': { 'padding': 'px-3 py-2.5', 'paddingCollapsed': 'p-4', 'text': 'text-sm', 'iconSize': 'md', 'gap': 'gap-4', 'rounded': 'rounded-lg' } } %} {# Couleurs par scheme : blue (Bubul) ou violet (SAM) #} {% set schemeColors = colorScheme == 'violet' ? { 'hoverGradient': 'hover:bg-[linear-gradient(135deg,rgba(139,92,246,0.15)_0%,rgba(167,139,250,0.12)_100%)] hover:text-cohorts-dark', 'activeGradient': 'bg-[linear-gradient(135deg,rgba(139,92,246,0.15)_0%,rgba(167,139,250,0.12)_100%)] text-cohorts-dark font-semibold', 'iconColor': 'cohorts', 'iconColorActive': 'cohorts' } : { 'hoverGradient': 'hover:bg-[linear-gradient(135deg,rgba(12,129,228,0.15)_0%,rgba(58,158,235,0.12)_100%)] hover:text-primary-dark', 'activeGradient': 'bg-[linear-gradient(135deg,rgba(12,129,228,0.15)_0%,rgba(58,158,235,0.12)_100%)] text-primary-dark font-semibold', 'iconColor': 'primary', 'iconColorActive': 'primary' } %} {# Variantes avec styles proches de l'ancien design sidebar #} {% set variantConfig = { 'default': { 'base': 'text-gray-600 ' ~ schemeColors.hoverGradient, 'active': schemeColors.activeGradient, 'iconColor': schemeColors.iconColor, 'iconColorActive': schemeColors.iconColorActive }, 'primary': { 'base': 'text-gray-600 hover:bg-primary hover:text-white', 'active': 'bg-primary text-white font-semibold', 'iconColor': 'primary', 'iconColorActive': 'white' }, 'minimal': { 'base': 'text-gray-500 hover:text-primary-dark', 'active': 'text-primary font-semibold', 'iconColor': 'gray', 'iconColorActive': 'primary' } } %} {% set sConfig = sizeConfig[size] ?? sizeConfig['md'] %} {% set vConfig = variantConfig[variant] ?? variantConfig['default'] %} {% set containerClasses = [ 'relative group flex items-center w-full min-w-0 my-1 transition-all duration-200 ease-out font-primary font-medium', sConfig.gap, sConfig.padding, 'group-data-[collapsed=true]/sidebar:' ~ sConfig.paddingCollapsed, 'group-data-[collapsed=true]/sidebar:justify-center', 'group-data-[collapsed=true]/sidebar:hover:scale-105', sConfig.rounded, (not locked and not disabled) ? (toolColorHex ? 'nav-item--tool text-gray-600' : (active ? vConfig.active : vConfig.base)) : '', disabled ? 'opacity-45 pointer-events-none cursor-not-allowed text-gray-400' : '', locked ? (proBadge ? 'cursor-pointer text-gray-400' : 'pointer-events-none cursor-not-allowed text-gray-400') : '', class ]|join(' ')|trim %} {# Couleur de l'icône : gris si locked/disabled, sinon couleur normale #} {% if locked or disabled %} {% set iconColor = 'gray' %} {% else %} {% set iconColor = active ? vConfig.iconColorActive : vConfig.iconColor %} {% endif %} {# ============================================================================ RENDU HTML ============================================================================ #} {# Icône #} {% if icon %} {% include '_atoms/icon/icon.html.twig' with { name: icon, size: sConfig.iconSize, color: iconColor, colorPrimary: (toolColorHex and not locked and not disabled) ? toolColorHex : null, colorSecondary: (toolColorSecondary and not locked and not disabled) ? toolColorSecondary : null, opacitySecondary: '0.35' } only %} {% endif %} {# Label (masqué en mode collapsed via CSS) #} {{ label }} {# Badge PRO (outil premium — utilisateur sans accès) : prioritaire sur le badge nouveauté. #} {% if proBadge %} {% include '_atoms/badge/pro-badge.html.twig' only %} {% elseif isNew %} {% include '_atoms/badge/badge.html.twig' with { label: newLabel, variant: 'warning', customColor: (toolColorHex and not locked and not disabled) ? toolColorHex : null, size: 'xs' } only %} {% endif %} {# Badge #} {% if badge %} {% include '_atoms/badge/badge.html.twig' with { label: badge, variant: badgeVariant ?? (active ? 'primary' : 'neutral'), size: badgeVariant == 'count' ? 'count' : 'xs' } only %} {% endif %} {# Cadenas (verrouillé) — masqué pour un outil PRO : le badge PRO tient lieu d'indicateur. #} {% if locked and not proBadge %} {% include '_atoms/icon/icon.html.twig' with { name: 'lock', size: 'sm', color: 'error' } only %} {% endif %} {# Indicateur externe #} {% if external %} {% include '_atoms/icon/icon.html.twig' with { name: 'exit', size: 'sm', color: 'gray' } only %} {% endif %} {# Badge en mode collapsed (point) - affiché seulement en collapsed #} {% if badge or isNew %} {% endif %} {# Cadenas en mode collapsed (point rouge) - affiché seulement en collapsed #} {% if locked %} {% endif %}