# 🎨 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) ```javascript 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` : ```javascript localStorage.getItem('benchtools_icon_pack') // 'emoji', 'fontawesome-solid', etc. ``` --- ## 💻 Utilisation ### Via l'interface Settings 1. Ouvrir **Settings** : [http://localhost:8087/settings.html](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 ```javascript // 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 ```javascript // 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: ``` #### Appliquer un pack programmatiquement ```javascript // 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) ```html ``` #### Après (système dynamique) ```html ``` #### Meilleure approche (génération JavaScript) ```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 ```css /* 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 : ```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` ```javascript const ICON_PACKS = { // ... packs existants 'mon-pack': { name: 'Mon Pack Personnalisé', description: 'Description de mon pack', icons: { 'add': '➕', // ou 'edit': '✏️', 'delete': '🗑️', 'save': '💾', // ... autres icônes } } }; ``` #### 2. Ajouter l'option dans `settings.html` ```html ``` #### 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. ```javascript 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. ```javascript 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. ```javascript const icon = window.IconManager.getIcon('delete', '🗑️'); // Retourne: 'Delete' // ou '🗑️' selon le pack ``` ### `IconManager.getAllPacks()` Liste tous les packs disponibles. ```javascript const packs = window.IconManager.getAllPacks(); // Retourne: ['emoji', 'fontawesome-solid', 'fontawesome-regular', 'icons8'] ``` ### `IconManager.getPackInfo(packName)` Récupère les informations d'un pack. ```javascript 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. ```javascript 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 ```javascript // 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 : ```javascript document.documentElement.style.setProperty('--button-icon-size', '20px'); ``` ### Le pack ne se sauvegarde pas **Solution** : 1. Vérifier que localStorage est activé : ```javascript console.log(localStorage.getItem('benchtools_icon_pack')); ``` 2. Vider le cache du navigateur (Ctrl+Shift+Del) 3. 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 - [FEATURE_THEME_SYSTEM.md](FEATURE_THEME_SYSTEM.md) - Système de thèmes - [GUIDE_THEMES.md](GUIDE_THEMES.md) - Guide utilisateur des thèmes - [frontend/css/themes/README.md](../frontend/css/themes/README.md) - Guide de création de thèmes ### Ressources externes - [FontAwesome Icons](https://fontawesome.com/icons) - Catalogue complet FontAwesome - [Icons8](https://icons8.com/) - Bibliothèque Icons8 - [Emojipedia](https://emojipedia.org/) - Référence Unicode emojis --- ## 📝 Exemple complet d'intégration ### Avant (ancien code) ```html ``` ### Après (nouveau système) #### HTML ```html
``` #### JavaScript ```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 ```html ``` ### 2. Préférer createIconButton() ```javascript // ✅ BON - Génération via helper const btn = createIconButton('save', 'Enregistrer', 'btn btn-primary', 'save()'); // ❌ MAUVAIS - HTML en dur const btn = ''; ``` ### 3. Écouter iconPackChanged pour les mises à jour ```javascript // ✅ 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 ```javascript // ✅ 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