14 KiB
🎨 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
-
Emojis Unicode (par défaut)
- Emojis colorés natifs
- Pas de dépendance externe
- Compatibilité universelle
- Exemples : ➕ ✏️ 🗑️ 💾 📤
-
FontAwesome Solid
- Icônes FontAwesome pleines (bold)
- Style moderne et professionnel
- Icônes SVG monochromes
- S'adaptent à la couleur du bouton
-
FontAwesome Regular
- Icônes FontAwesome fines (outline)
- Style minimaliste et élégant
- Variante légère de FontAwesome Solid
- Parfait pour un design épuré
-
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- Ajouteredit- Éditerdelete- Supprimersave- Enregistrerupload- Upload/Téléverserdownload- Téléchargerimage- Imagefile- Fichierpdf- PDFlink- Lien/URLrefresh- Rafraîchirsearch- Recherchersettings- Paramètresclose- Fermercheck- Validerwarning- Avertissementinfo- Informationcopy- 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
- Ouvrir Settings : http://localhost:8087/settings.html
- Section "Pack d'icônes"
- Sélectionner un pack dans la liste déroulante
- Prévisualiser les icônes en temps réel
- Cliquer sur "Appliquer le pack d'icônes"
- 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
- Ouvrir la page Settings
- Changer de pack dans la section "Pack d'icônes"
- Observer l'aperçu en temps réel
- Cliquer sur "Appliquer"
- 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 :
- Vérifier que
icon-manager.jsest chargé dans la page - Ouvrir la console (F12) et vérifier les erreurs
- Vérifier que les boutons ont l'attribut
data-icon - Essayer de recharger la page avec Ctrl+F5
Les icônes SVG n'apparaissent pas
Solution :
- Vérifier que les fichiers SVG existent dans
frontend/icons/svg/fa/ - Vérifier les permissions des fichiers
- Ouvrir la console réseau (F12 > Network) et chercher les erreurs 404
- Vérifier le chemin dans
icon-manager.js
Les icônes sont trop grandes/petites
Solution :
- Aller dans Settings > Préférences d'affichage
- Ajuster "Taille des icônes de bouton"
- Ou modifier manuellement la variable CSS :
document.documentElement.style.setProperty('--button-icon-size', '20px');
Le pack ne se sauvegarde pas
Solution :
- Vérifier que localStorage est activé :
console.log(localStorage.getItem('benchtools_icon_pack'));
- Vider le cache du navigateur (Ctrl+Shift+Del)
- 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 - Système de thèmes
- GUIDE_THEMES.md - Guide utilisateur des thèmes
- frontend/css/themes/README.md - Guide de création de thèmes
Ressources externes
- FontAwesome Icons - Catalogue complet FontAwesome
- Icons8 - Bibliothèque Icons8
- Emojipedia - Référence Unicode emojis
📝 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