# Exemples de Code - Système de Thèmes Ce document contient des exemples pratiques pour travailler avec le système de thèmes. ## Exemples Utilisateur ### Changer de thème via la console du navigateur ```javascript // Appliquer le thème Dracula window.themeManager.applyTheme('dracula'); // Appliquer le thème Nord window.themeManager.applyTheme('nord'); // Obtenir le thème actuel console.log(window.themeManager.getCurrentTheme()); // Obtenir la liste de tous les thèmes console.log(window.themeManager.getThemes()); ``` ### Vérifier quel thème est actif ```javascript // Méthode 1 : Via le ThemeManager const currentTheme = window.themeManager.getCurrentTheme(); console.log('Thème actif:', currentTheme); // Méthode 2 : Via l'attribut data-theme const themeAttribute = document.documentElement.getAttribute('data-theme'); console.log('Thème actif:', themeAttribute); // Méthode 3 : Via localStorage const savedTheme = localStorage.getItem('app-theme'); console.log('Thème sauvegardé:', savedTheme); ``` ## Exemples Développeur ### Créer un nouveau thème personnalisé #### 1. Définir les variables CSS dans `themes.css` ```css /* =========================== THEME: GITHUB DARK =========================== */ [data-theme="github-dark"] { --bg-primary: #0d1117; --bg-secondary: #161b22; --bg-tertiary: #21262d; --bg-elevated: #30363d; --border-primary: #30363d; --border-secondary: #21262d; --text-primary: #c9d1d9; --text-secondary: #8b949e; --text-muted: #484f58; --accent-primary: #58a6ff; --accent-primary-hover: #79c0ff; --accent-secondary: #1f6feb; --accent-secondary-hover: #388bfd; --success: #3fb950; --warning: #d29922; --error: #f85149; } /* Couleurs de prévisualisation */ .theme-card[data-theme="github-dark"] .theme-preview-color:nth-child(1) { background: #0d1117; } .theme-card[data-theme="github-dark"] .theme-preview-color:nth-child(2) { background: #58a6ff; } .theme-card[data-theme="github-dark"] .theme-preview-color:nth-child(3) { background: #1f6feb; } .theme-card[data-theme="github-dark"] .theme-preview-color:nth-child(4) { background: #c9d1d9; } ``` #### 2. Ajouter le thème dans `theme-manager.js` ```javascript // Dans le constructeur de ThemeManager this.themes = [ // ... thèmes existants { id: 'github-dark', name: 'GitHub Dark', icon: '🐙', description: 'Thème inspiré de GitHub avec des tons bleus et gris' } ]; ``` #### 3. Ajouter la carte dans `index.html` ```html
🐙 GitHub Dark

Thème inspiré de GitHub avec des tons bleus et gris

``` ### Écouter les changements de thème ```javascript // Créer un MutationObserver pour détecter les changements de thème const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') { const newTheme = document.documentElement.getAttribute('data-theme'); console.log('Thème changé vers:', newTheme); // Faire quelque chose lors du changement de thème // Par exemple, mettre à jour CodeMirror, Highlight.js, etc. } }); }); // Observer les changements sur l'élément observer.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] }); ``` ### Créer un thème dynamique basé sur l'heure ```javascript function applyTimeBasedTheme() { const hour = new Date().getHours(); if (hour >= 6 && hour < 18) { // Jour (6h-18h) - utiliser un thème plus lumineux window.themeManager.applyTheme('solarized-dark'); } else if (hour >= 18 && hour < 22) { // Soirée (18h-22h) - utiliser un thème doux window.themeManager.applyTheme('one-dark'); } else { // Nuit (22h-6h) - utiliser un thème très sombre window.themeManager.applyTheme('material-dark'); } } // Appliquer au chargement applyTimeBasedTheme(); // Vérifier toutes les heures setInterval(applyTimeBasedTheme, 3600000); ``` ### Thème aléatoire au chargement ```javascript function applyRandomTheme() { const themes = window.themeManager.getThemes(); const randomIndex = Math.floor(Math.random() * themes.length); const randomTheme = themes[randomIndex]; window.themeManager.applyTheme(randomTheme.id); console.log('Thème aléatoire appliqué:', randomTheme.name); } // Utilisation // applyRandomTheme(); ``` ### Créer un raccourci clavier ```javascript // Ctrl+T pour ouvrir/fermer la modale de thèmes document.addEventListener('keydown', (e) => { // Ctrl+T ou Cmd+T if ((e.ctrlKey || e.metaKey) && e.key === 't') { e.preventDefault(); const modal = document.getElementById('theme-modal'); if (modal.style.display === 'flex') { window.closeThemeModal(); } else { window.openThemeModal(); } } }); // Ctrl+Shift+T pour passer au thème suivant document.addEventListener('keydown', (e) => { if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'T') { e.preventDefault(); const themes = window.themeManager.getThemes(); const currentTheme = window.themeManager.getCurrentTheme(); const currentIndex = themes.findIndex(t => t.id === currentTheme); const nextIndex = (currentIndex + 1) % themes.length; window.themeManager.applyTheme(themes[nextIndex].id); console.log('Thème suivant:', themes[nextIndex].name); } }); ``` ### Adapter CodeMirror au thème ```javascript // Mapper les thèmes de l'app aux thèmes CodeMirror const codemirrorThemeMap = { 'material-dark': 'material-darker', 'monokai-dark': 'monokai', 'dracula': 'dracula', 'one-dark': 'one-dark', 'solarized-dark': 'solarized dark', 'nord': 'nord' }; // Observer les changements de thème const observer = new MutationObserver(() => { const currentTheme = window.themeManager.getCurrentTheme(); const cmTheme = codemirrorThemeMap[currentTheme] || 'material-darker'; // Si vous utilisez CodeMirror if (window.editor && typeof window.editor.setOption === 'function') { window.editor.setOption('theme', cmTheme); console.log('CodeMirror thème changé vers:', cmTheme); } }); observer.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] }); ``` ### Exporter/Importer les préférences utilisateur ```javascript // Exporter les préférences function exportPreferences() { const prefs = { theme: window.themeManager.getCurrentTheme(), timestamp: new Date().toISOString() }; const blob = new Blob([JSON.stringify(prefs, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'project-notes-preferences.json'; a.click(); URL.revokeObjectURL(url); } // Importer les préférences function importPreferences(file) { const reader = new FileReader(); reader.onload = (e) => { try { const prefs = JSON.parse(e.target.result); if (prefs.theme) { window.themeManager.applyTheme(prefs.theme); console.log('Préférences importées:', prefs); } } catch (error) { console.error('Erreur lors de l\'importation:', error); } }; reader.readAsText(file); } ``` ### Créer un prévisualisateur de thème en direct ```javascript // Créer une fonction pour prévisualiser un thème sans le sauvegarder function previewTheme(themeId) { // Sauvegarder le thème actuel const originalTheme = window.themeManager.getCurrentTheme(); // Appliquer temporairement le nouveau thème document.documentElement.setAttribute('data-theme', themeId); // Retourner une fonction pour annuler return () => { document.documentElement.setAttribute('data-theme', originalTheme); }; } // Utilisation const cancelPreview = previewTheme('dracula'); // Après quelques secondes, annuler setTimeout(() => { cancelPreview(); }, 3000); ``` ## Intégration avec d'autres bibliothèques ### Highlight.js ```javascript // Adapter le thème Highlight.js const highlightThemeMap = { 'material-dark': 'atom-one-dark', 'monokai-dark': 'monokai', 'dracula': 'dracula', 'one-dark': 'atom-one-dark', 'solarized-dark': 'solarized-dark', 'nord': 'nord' }; function updateHighlightTheme(themeId) { const hlTheme = highlightThemeMap[themeId] || 'atom-one-dark'; const linkElement = document.querySelector('link[href*="highlight.js"]'); if (linkElement) { linkElement.href = `https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/styles/${hlTheme}.min.css`; } } ``` ### Marked.js (déjà intégré) Le système de thèmes fonctionne automatiquement avec Marked.js car il utilise les variables CSS globales. ## Débogage ### Afficher toutes les variables CSS actives ```javascript // Obtenir toutes les variables CSS définies sur :root function getCurrentThemeVariables() { const root = document.documentElement; const styles = getComputedStyle(root); const variables = {}; // Liste des variables de thème const varNames = [ '--bg-primary', '--bg-secondary', '--bg-tertiary', '--bg-elevated', '--border-primary', '--border-secondary', '--text-primary', '--text-secondary', '--text-muted', '--accent-primary', '--accent-secondary', '--success', '--warning', '--error' ]; varNames.forEach(varName => { variables[varName] = styles.getPropertyValue(varName).trim(); }); return variables; } // Afficher console.table(getCurrentThemeVariables()); ``` ### Vérifier si un thème est chargé ```javascript function isThemeLoaded(themeId) { // Appliquer temporairement le thème const originalTheme = document.documentElement.getAttribute('data-theme'); document.documentElement.setAttribute('data-theme', themeId); // Vérifier si les variables CSS sont définies const primaryBg = getComputedStyle(document.documentElement) .getPropertyValue('--bg-primary').trim(); // Restaurer le thème original document.documentElement.setAttribute('data-theme', originalTheme); return primaryBg !== ''; } // Vérifier tous les thèmes window.themeManager.getThemes().forEach(theme => { console.log(theme.name, ':', isThemeLoaded(theme.id) ? '✅' : '❌'); }); ``` ## Conclusion Ces exemples couvrent la plupart des cas d'usage courants. Pour plus d'informations, consultez : - `docs/THEMES.md` - Documentation technique complète - `docs/GUIDE_THEMES.md` - Guide utilisateur - `frontend/src/theme-manager.js` - Code source du gestionnaire