{# # ============================================================================ # MOLECULE: ACTION BAR # ============================================================================ # # Groupe de boutons d'action pour les lignes de tableau ou les cartes. # Idéal pour les opérations CRUD (éditer, supprimer, etc.). # # ============================================================================ # COMPOSITION (Atomes utilisés) # ============================================================================ # # - _atoms/icon/icon.html.twig # - _atoms/button/button.html.twig # - _atoms/tooltip/tooltip.html.twig (optionnel) # # ============================================================================ # PARAMÈTRES # ============================================================================ # # | Paramètre | Type | Défaut | Description | # |---------------|---------|-----------|-----------------------------------| # | actions | array | (requis) | Liste des actions | # | └ icon | string | (requis) | Nom de l'icône | # | └ label | string | null | Texte du bouton (si non icon-only)| # | └ title | string | null | Tooltip au survol | # | └ href | string | null | URL (rend un lien) | # | └ variant | string | 'ghost' | ghost, danger, primary | # | └ confirm | string | null | Message de confirmation | # | └ disabled | bool | false | Désactiver l'action | # | └ data | object | null | Attributs data-* supplémentaires | # | size | string | 'sm' | xs, sm, md | # | iconOnly | bool | true | Afficher uniquement les icônes | # | class | string | '' | Classes additionnelles | # # ============================================================================ # EXEMPLES D'UTILISATION # ============================================================================ # # Actions CRUD: # {% include '_molecules/action-bar/action-bar.html.twig' with { # actions: [ # { icon: 'eye', title: 'Voir', href: '/view/1' }, # { icon: 'edit', title: 'Modifier', href: '/edit/1' }, # { icon: 'trash', title: 'Supprimer', variant: 'danger', confirm: 'Êtes-vous sûr ?' } # ] # } %} # # Avec labels: # {% include '_molecules/action-bar/action-bar.html.twig' with { # actions: [ # { icon: 'edit', label: 'Modifier', href: '/edit/1' }, # { icon: 'trash', label: 'Supprimer', variant: 'danger' } # ], # iconOnly: false # } %} # # ============================================================================ #} {# ============================================================================ CONFIGURATION DES VALEURS PAR DÉFAUT ============================================================================ #} {% set actions = actions ?? [] %} {% set size = size ?? 'sm' %} {% set iconOnly = iconOnly ?? true %} {% set class = class ?? '' %} {# ============================================================================ CLASSES TAILWIND ============================================================================ #} {% set sizeConfig = { 'xs': { 'button': 'p-1', 'icon': 'xs', 'gap': 'gap-0.5', 'text': 'text-xs' }, 'sm': { 'button': 'p-1.5', 'icon': 'sm', 'gap': 'gap-1', 'text': 'text-sm' }, 'md': { 'button': 'p-2', 'icon': 'md', 'gap': 'gap-1.5', 'text': 'text-sm' } } %} {% set sConfig = sizeConfig[size] ?? sizeConfig['sm'] %} {% set variantConfig = { 'ghost': { 'base': 'text-gray-500 hover:text-gray-700 hover:bg-gray-100', 'icon': 'muted' }, 'primary': { 'base': 'text-primary hover:text-primary-dark hover:bg-primary/10', 'icon': 'primary' }, 'danger': { 'base': 'text-red-500 hover:text-red-700 hover:bg-red-50', 'icon': 'error' }, 'success': { 'base': 'text-green-500 hover:text-green-700 hover:bg-green-50', 'icon': 'success' } } %} {# ============================================================================ RENDU HTML ============================================================================ #}
{% for action in actions %} {% set vConfig = variantConfig[action.variant ?? 'ghost'] ?? variantConfig['ghost'] %} {% set tag = action.href is defined and action.href ? 'a' : 'button' %} {% set isDisabled = action.disabled ?? false %} <{{ tag }} {% if tag == 'a' and not isDisabled %} href="{{ action.href }}" {% elseif tag == 'button' %} type="button" {% endif %} {% if isDisabled %}disabled aria-disabled="true"{% endif %} {% if action.title is defined and action.title %}title="{{ action.title }}"{% endif %} {% if action.confirm is defined and action.confirm %} data-confirm="{{ action.confirm }}" onclick="return confirm(this.dataset.confirm)" {% endif %} {% if action.data is defined %} {% for key, val in action.data %} data-{{ key }}="{{ val }}" {% endfor %} {% endif %} class="inline-flex items-center justify-center {{ sConfig.gap }} {{ sConfig.button }} rounded-lg transition-all duration-200 {% if isDisabled %} opacity-50 cursor-not-allowed {% else %} {{ vConfig.base }} cursor-pointer {% endif %}" > {% if action.icon is defined and action.icon %} {% include '_atoms/icon/icon.html.twig' with { name: action.icon, size: sConfig.icon, color: isDisabled ? 'muted' : 'current' } only %} {% endif %} {% if not iconOnly and action.label is defined and action.label %} {{ action.label }} {% endif %} {% endfor %}