Files
serv_benchmark/docs/FEATURE_ICON_PACKS.md
2026-01-11 23:41:30 +01:00

14 KiB
Raw Blame History

🎨 Feature: Icon Packs - Système de personnalisation des icônes

📋 Vue d'ensemble

Le système Icon Packs permet aux utilisateurs de choisir entre différents styles d'icônes pour les boutons d'action de l'application (Ajouter, Supprimer, Éditer, Enregistrer, Upload, etc.).

Problème résolu

Auparavant, l'application utilisait uniquement des emojis Unicode (🗑️, 💾, ✏️) pour les icônes. Ce système apporte :

  • Flexibilité : Choix entre emojis, FontAwesome (solid/regular), et Icons8
  • Cohérence visuelle : Icônes uniformes selon le pack choisi
  • Accessibilité : Alternative aux emojis pour les utilisateurs qui préfèrent des icônes SVG
  • Personnalisation : Adaptation au goût et aux préférences de chaque utilisateur

🎯 Fonctionnalités

Packs d'icônes disponibles

  1. Emojis Unicode (par défaut)

    • Emojis colorés natifs
    • Pas de dépendance externe
    • Compatibilité universelle
    • Exemples : ✏️ 🗑️ 💾 📤
  2. FontAwesome Solid

    • Icônes FontAwesome pleines (bold)
    • Style moderne et professionnel
    • Icônes SVG monochromes
    • S'adaptent à la couleur du bouton
  3. FontAwesome Regular

    • Icônes FontAwesome fines (outline)
    • Style minimaliste et élégant
    • Variante légère de FontAwesome Solid
    • Parfait pour un design épuré
  4. Icons8 PNG

    • Mix des icônes Icons8 existantes (PNG)
    • Combine emojis et icônes PNG
    • Utilise les icônes déjà présentes dans le projet
    • Style coloré et moderne

Icônes supportées

Le système gère les icônes suivantes :

  • add - Ajouter
  • edit - Éditer
  • delete - Supprimer
  • save - Enregistrer
  • upload - Upload/Téléverser
  • download - Télécharger
  • image - Image
  • file - Fichier
  • pdf - PDF
  • link - Lien/URL
  • refresh - Rafraîchir
  • search - Rechercher
  • settings - Paramètres
  • close - Fermer
  • check - Valider
  • warning - Avertissement
  • info - Information
  • copy - Copier

🏗️ Architecture

Fichiers créés

frontend/
├── js/
│   └── icon-manager.js          # Gestionnaire de packs d'icônes
├── css/
│   └── components.css            # CSS pour .btn-icon (mis à jour)
└── icons/
    └── svg/
        └── fa/
            ├── solid/            # FontAwesome Solid SVG
            └── regular/          # FontAwesome Regular SVG

Structure du gestionnaire d'icônes

icon-manager.js - Module auto-initialisé (IIFE)

const IconManager = {
  packs: ICON_PACKS,               // Configuration des packs
  getCurrentPack(),                // Récupère le pack actif
  applyPack(packName),             // Applique un nouveau pack
  getIcon(iconName, fallback),     // Récupère une icône
  getAllPacks(),                   // Liste tous les packs
  getPackInfo(packName),           // Infos sur un pack
  createButton(...),               // Helper pour créer un bouton
  updateAllButtons()               // Met à jour les boutons existants
};

Stockage

Le pack d'icônes choisi est stocké dans localStorage :

localStorage.getItem('benchtools_icon_pack') // 'emoji', 'fontawesome-solid', etc.

💻 Utilisation

Via l'interface Settings

  1. Ouvrir Settings : http://localhost:8087/settings.html
  2. Section "Pack d'icônes"
  3. Sélectionner un pack dans la liste déroulante
  4. Prévisualiser les icônes en temps réel
  5. Cliquer sur "Appliquer le pack d'icônes"
  6. La page se recharge et applique les nouvelles icônes

Via JavaScript

Récupérer une icône

// Récupérer l'icône "delete" selon le pack actif
const deleteIcon = window.IconManager.getIcon('delete');

// Avec fallback personnalisé
const saveIcon = window.IconManager.getIcon('save', '💾');

// Ou via la fonction helper dans utils.js
const addIcon = getIcon('add', '+');

Créer un bouton avec icône

// Via IconManager
const btnHtml = window.IconManager.createButton('delete', 'Supprimer', 'btn btn-danger');

// Via helper function (utils.js)
const btnHtml = createIconButton('add', 'Ajouter', 'btn btn-primary', 'addItem()');
// Résultat: <button class="btn btn-primary" onclick="addItem()" data-icon="add">
//             <span class="btn-icon-wrapper">[icône]</span> Ajouter
//           </button>

Appliquer un pack programmatiquement

// Changer le pack d'icônes
window.IconManager.applyPack('fontawesome-solid');

// Écouter les changements de pack
window.addEventListener('iconPackChanged', (event) => {
  console.log('Nouveau pack:', event.detail.pack);
  console.log('Nom:', event.detail.packName);
});

Exemple dans le HTML

Avant (emojis en dur)

<button class="btn btn-danger" onclick="deleteItem()">
  🗑️ Supprimer
</button>

Après (système dynamique)

<button class="btn btn-danger" onclick="deleteItem()" data-icon="delete">
  <span class="btn-icon-wrapper"></span> Supprimer
</button>

<script>
// L'icône est injectée automatiquement au chargement
document.addEventListener('DOMContentLoaded', () => {
  const icon = window.IconManager.getIcon('delete');
  document.querySelector('[data-icon="delete"] .btn-icon-wrapper').innerHTML = icon;
});
</script>

Meilleure approche (génération JavaScript)

// Dans votre code de rendu
function renderDeleteButton() {
  return createIconButton('delete', 'Supprimer', 'btn btn-danger', 'deleteItem()');
}

// Ou directement
container.innerHTML += createIconButton('add', 'Ajouter', 'btn btn-primary', 'addItem()');

🎨 Styling CSS

Classes CSS pour les icônes

/* Icône SVG dans un bouton */
.btn-icon {
  width: var(--button-icon-size, 24px);
  height: var(--button-icon-size, 24px);
  vertical-align: middle;
  filter: brightness(0) invert(1); /* Blanc par défaut */
}

/* Wrapper pour mise à jour dynamique */
.btn-icon-wrapper {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Adaptation selon le type de bouton */
.btn-primary .btn-icon { filter: brightness(0) invert(1); }
.btn-secondary .btn-icon { filter: brightness(0.8); }
.btn-danger .btn-icon { filter: brightness(0) invert(1); }

Variables CSS

Les tailles d'icônes sont contrôlables via variables CSS :

:root {
  --section-icon-size: 32px;  /* Icônes dans les titres */
  --button-icon-size: 24px;   /* Icônes dans les boutons */
}

Ces variables sont modifiables dans Settings > Préférences d'affichage.


📦 Configuration des packs

Ajouter un nouveau pack

1. Éditer icon-manager.js

const ICON_PACKS = {
  // ... packs existants
  'mon-pack': {
    name: 'Mon Pack Personnalisé',
    description: 'Description de mon pack',
    icons: {
      'add': '',  // ou <img src="...">
      'edit': '✏️',
      'delete': '🗑️',
      'save': '💾',
      // ... autres icônes
    }
  }
};

2. Ajouter l'option dans settings.html

<select id="iconPack" class="form-control">
  <!-- ... options existantes -->
  <option value="mon-pack">Mon Pack Personnalisé</option>
</select>

3. (Optionnel) Ajouter des assets

Si vous utilisez des SVG/PNG personnalisés :

  • Placer les fichiers dans frontend/icons/custom/
  • Référencer avec le bon chemin dans la config

🔧 API du gestionnaire d'icônes

IconManager.getCurrentPack()

Retourne le nom du pack actuellement actif.

const currentPack = window.IconManager.getCurrentPack();
// Retourne: 'emoji' | 'fontawesome-solid' | 'fontawesome-regular' | 'icons8'

IconManager.applyPack(packName)

Change le pack d'icônes et sauvegarde dans localStorage.

window.IconManager.applyPack('fontawesome-solid');
// Retourne: true (succès) ou false (pack inconnu)

IconManager.getIcon(iconName, fallback)

Récupère le HTML d'une icône selon le pack actif.

const icon = window.IconManager.getIcon('delete', '🗑️');
// Retourne: '<img src="icons/svg/fa/solid/trash-can.svg" class="btn-icon" alt="Delete">'
// ou '🗑️' selon le pack

IconManager.getAllPacks()

Liste tous les packs disponibles.

const packs = window.IconManager.getAllPacks();
// Retourne: ['emoji', 'fontawesome-solid', 'fontawesome-regular', 'icons8']

IconManager.getPackInfo(packName)

Récupère les informations d'un pack.

const packInfo = window.IconManager.getPackInfo('fontawesome-solid');
// Retourne: { name: 'FontAwesome Solid', description: '...', icons: {...} }

IconManager.updateAllButtons()

Met à jour dynamiquement toutes les icônes de la page.

window.IconManager.updateAllButtons();
// Parcourt tous les [data-icon] et met à jour leur contenu

🧪 Tests

Tester un pack d'icônes

  1. Ouvrir la page Settings
  2. Changer de pack dans la section "Pack d'icônes"
  3. Observer l'aperçu en temps réel
  4. Cliquer sur "Appliquer"
  5. Vérifier que toutes les pages utilisent le nouveau pack

Console de développement

// Lister tous les packs
console.log(window.IconManager.getAllPacks());

// Tester chaque icône d'un pack
const pack = window.IconManager.getPackInfo('fontawesome-solid');
Object.keys(pack.icons).forEach(iconName => {
  console.log(iconName, pack.icons[iconName]);
});

// Forcer un pack sans recharger
window.IconManager.applyPack('fontawesome-regular');
window.IconManager.updateAllButtons();

🐛 Dépannage

Les icônes ne changent pas

Solution :

  1. Vérifier que icon-manager.js est chargé dans la page
  2. Ouvrir la console (F12) et vérifier les erreurs
  3. Vérifier que les boutons ont l'attribut data-icon
  4. Essayer de recharger la page avec Ctrl+F5

Les icônes SVG n'apparaissent pas

Solution :

  1. Vérifier que les fichiers SVG existent dans frontend/icons/svg/fa/
  2. Vérifier les permissions des fichiers
  3. Ouvrir la console réseau (F12 > Network) et chercher les erreurs 404
  4. Vérifier le chemin dans icon-manager.js

Les icônes sont trop grandes/petites

Solution :

  1. Aller dans Settings > Préférences d'affichage
  2. Ajuster "Taille des icônes de bouton"
  3. Ou modifier manuellement la variable CSS :
document.documentElement.style.setProperty('--button-icon-size', '20px');

Le pack ne se sauvegarde pas

Solution :

  1. Vérifier que localStorage est activé :
console.log(localStorage.getItem('benchtools_icon_pack'));
  1. Vider le cache du navigateur (Ctrl+Shift+Del)
  2. Tester en navigation privée pour isoler le problème

📊 Comparaison des packs

Pack Type Taille Couleur Avantages Inconvénients
Emojis Unicode Natif Variable Oui Universel, pas de dépendance Rendu variable selon OS
FontAwesome Solid SVG 24px Mono Professionnel, cohérent Nécessite assets SVG
FontAwesome Regular SVG 24px Mono Élégant, minimaliste Moins visible que Solid
Icons8 PNG PNG 48px Oui Coloré, moderne Mix de styles

🔮 Évolutions futures

Fonctionnalités prévues

  • Import de packs personnalisés : Permettre l'upload d'un fichier JSON définissant un pack
  • Éditeur visuel de pack : Interface pour créer son propre pack
  • Thèmes d'icônes : Packs adaptés automatiquement au thème actif
  • Icônes animées : Support des GIF ou animations CSS
  • Marketplace de packs : Partager et télécharger des packs créés par la communauté

Améliorations techniques

  • Lazy loading des icônes SVG
  • Sprite SVG pour réduire les requêtes HTTP
  • Support des web fonts (Font Awesome CDN)
  • Cache des icônes dans IndexedDB
  • Mode hors-ligne avec Service Worker

📚 Ressources

Documentation connexe

Ressources externes


📝 Exemple complet d'intégration

Avant (ancien code)

<button class="btn btn-primary" onclick="addItem()"> Ajouter</button>
<button class="btn btn-danger" onclick="deleteItem()">🗑️ Supprimer</button>

Après (nouveau système)

HTML

<div id="actionButtons"></div>

JavaScript

// Fonction de rendu
function renderActionButtons() {
  const container = document.getElementById('actionButtons');

  const buttons = [
    createIconButton('add', 'Ajouter', 'btn btn-primary', 'addItem()'),
    createIconButton('delete', 'Supprimer', 'btn btn-danger', 'deleteItem()')
  ];

  container.innerHTML = buttons.join(' ');
}

// Rendu initial
document.addEventListener('DOMContentLoaded', renderActionButtons);

// Re-rendu lors du changement de pack
window.addEventListener('iconPackChanged', renderActionButtons);

🎓 Bonnes pratiques

1. Toujours utiliser data-icon

<!-- ✅ BON -->
<button class="btn" data-icon="delete" onclick="del()">
  <span class="btn-icon-wrapper"></span> Supprimer
</button>

<!-- ❌ MAUVAIS -->
<button class="btn" onclick="del()">🗑️ Supprimer</button>

2. Préférer createIconButton()

// ✅ BON - Génération via helper
const btn = createIconButton('save', 'Enregistrer', 'btn btn-primary', 'save()');

// ❌ MAUVAIS - HTML en dur
const btn = '<button class="btn btn-primary" onclick="save()">💾 Enregistrer</button>';

3. Écouter iconPackChanged pour les mises à jour

// ✅ BON - Re-render automatique
window.addEventListener('iconPackChanged', () => {
  renderMyComponent();
});

// ❌ MAUVAIS - Icônes statiques
// Pas de mise à jour après changement de pack

4. Fournir un fallback

// ✅ BON
const icon = getIcon('custom-icon', '❓');

// ❌ RISQUÉ
const icon = getIcon('custom-icon');
// Retourne '?' si l'icône n'existe pas

📄 Licence

Ce système fait partie de Linux BenchTools et est distribué sous la même licence que le projet principal.


Créé le : 2026-01-11 Auteur : Linux BenchTools Team Version : 1.0.0