240 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			240 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Système de Théming ObsiViewer - Documentation
 | ||
| 
 | ||
| ## Vue d'ensemble
 | ||
| 
 | ||
| Système de théming double dimension : **7 thèmes × 2 modes = 14 combinaisons**
 | ||
| 
 | ||
| - **Modes** : Light, Dark
 | ||
| - **Thèmes** : Light (default), Dark (default), Obsidian, Nord, Notion, GitHub, Discord, Monokai
 | ||
| 
 | ||
| ## Architecture
 | ||
| 
 | ||
| ### 1. Tokens CSS (`src/styles/themes.css`)
 | ||
| 
 | ||
| Tous les thèmes définissent un ensemble cohérent de tokens CSS :
 | ||
| 
 | ||
| ```css
 | ||
| /* Backgrounds */
 | ||
| --bg, --bg-main, --bg-muted
 | ||
| --card, --card-bg, --elevated
 | ||
| --sidebar-bg, --surface-1, --surface-2
 | ||
| 
 | ||
| /* Text */
 | ||
| --fg, --text-main, --text-muted, --muted
 | ||
| 
 | ||
| /* Borders */
 | ||
| --border
 | ||
| 
 | ||
| /* Brand & Accents */
 | ||
| --primary, --brand, --brand-700, --brand-800
 | ||
| --secondary, --accent
 | ||
| 
 | ||
| /* Status */
 | ||
| --success, --warning, --danger, --info
 | ||
| 
 | ||
| /* UI Elements */
 | ||
| --chip-bg, --link, --link-hover, --ring
 | ||
| 
 | ||
| /* Editor (CodeMirror 6) */
 | ||
| --editor-bg, --editor-fg, --editor-selection
 | ||
| --editor-gutter-bg, --editor-gutter-fg, --editor-cursor
 | ||
| 
 | ||
| /* Shadows */
 | ||
| --shadow-color, --scrollbar-thumb
 | ||
| ```
 | ||
| 
 | ||
| ### 2. Configuration Tailwind (`tailwind.config.js`)
 | ||
| 
 | ||
| Tous les tokens sont mappés dans Tailwind :
 | ||
| 
 | ||
| ```javascript
 | ||
| colors: {
 | ||
|   bg: 'var(--bg)',
 | ||
|   'bg-main': 'var(--bg-main)',
 | ||
|   fg: 'var(--fg)',
 | ||
|   surface1: 'var(--surface-1)',
 | ||
|   primary: 'var(--primary)',
 | ||
|   // ... etc
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### 3. ThemeService (`src/app/core/services/theme.service.ts`)
 | ||
| 
 | ||
| Service central qui gère :
 | ||
| - Mode : `'system' | 'light' | 'dark'`
 | ||
| - Thème : `'light' | 'dark' | 'obsidian' | 'nord' | 'notion' | 'github' | 'discord' | 'monokai'`
 | ||
| - Application sur `<html>` : classe `.dark` + attribut `data-theme`
 | ||
| - Persistance dans localStorage
 | ||
| - Observable `onPrefs$` pour réactivité
 | ||
| 
 | ||
| ### 4. CodeMirror 6 (`src/app/core/codemirror-themes.ts`)
 | ||
| 
 | ||
| Fonction `cm6ThemeFor(themeId, mode)` qui retourne les extensions CM6 appropriées pour chaque combinaison thème/mode.
 | ||
| 
 | ||
| ### 5. Anti-FOUC (`index.html`)
 | ||
| 
 | ||
| Script inline qui lit les préférences et applique le thème avant le chargement d'Angular :
 | ||
| 
 | ||
| ```javascript
 | ||
| (function () {
 | ||
|   const prefs = JSON.parse(localStorage.getItem('obsiviewer.preferences.v1') || '{}');
 | ||
|   const isDark = prefs.mode === 'dark' || (prefs.mode === 'system' && prefersDark);
 | ||
|   html.classList.toggle('dark', isDark);
 | ||
|   html.setAttribute('data-theme', prefs.theme || 'light');
 | ||
| })();
 | ||
| ```
 | ||
| 
 | ||
| ## Matrice des Thèmes
 | ||
| 
 | ||
| ### Light (Default)
 | ||
| - **Light mode** : Blanc pur, texte gris foncé, accents bleus
 | ||
| - **Dark mode** : N/A (thème light uniquement)
 | ||
| 
 | ||
| ### Dark (Default)
 | ||
| - **Light mode** : N/A (thème dark uniquement)
 | ||
| - **Dark mode** : Fond bleu-gris foncé, texte clair, accents bleus clairs
 | ||
| 
 | ||
| ### Obsidian
 | ||
| - **Light mode** : Beige chaud (#fafaf8), texte anthracite, accents terre
 | ||
| - **Dark mode** : Gris très foncé (#1e1e1e), texte clair, accents beiges
 | ||
| 
 | ||
| ### Nord
 | ||
| - **Light mode** : Blanc neigeux (#eceff4), texte bleu-gris, palette nordique pastel
 | ||
| - **Dark mode** : Bleu-gris arctique (#2e3440), texte givré, palette nordique
 | ||
| 
 | ||
| ### Notion
 | ||
| - **Light mode** : Blanc pur, texte charbon, minimaliste
 | ||
| - **Dark mode** : Noir profond (#171717), texte ivoire, contraste élevé
 | ||
| 
 | ||
| ### GitHub
 | ||
| - **Light mode** : Blanc, texte GitHub (#24292f), palette GitHub
 | ||
| - **Dark mode** : Dimmed dark (#0d1117), palette GitHub dark
 | ||
| 
 | ||
| ### Discord
 | ||
| - **Light mode** : Gris très clair (#f6f7f9), texte foncé, violet Discord
 | ||
| - **Dark mode** : Gris Discord (#2b2d31), texte clair, violet Discord
 | ||
| 
 | ||
| ### Monokai
 | ||
| - **Light mode** : Crème (#fbfbf7), texte foncé, accents verts/oranges atténués
 | ||
| - **Dark mode** : Vert-gris foncé (#272822), texte clair, palette Monokai classique
 | ||
| 
 | ||
| ## Utilisation dans les Composants
 | ||
| 
 | ||
| ### Classes Tailwind recommandées
 | ||
| 
 | ||
| ```html
 | ||
| <!-- Backgrounds -->
 | ||
| <div class="bg-card">Carte</div>
 | ||
| <div class="bg-surface1">Surface niveau 1</div>
 | ||
| <div class="bg-surface2">Surface niveau 2</div>
 | ||
| 
 | ||
| <!-- Text -->
 | ||
| <p class="text-main">Texte principal</p>
 | ||
| <p class="text-muted">Texte secondaire</p>
 | ||
| 
 | ||
| <!-- Borders -->
 | ||
| <div class="border border-border">Bordure</div>
 | ||
| 
 | ||
| <!-- Interactive -->
 | ||
| <button class="bg-primary text-white hover:bg-brand-700">
 | ||
|   Action
 | ||
| </button>
 | ||
| 
 | ||
| <!-- Links -->
 | ||
| <a class="text-link hover:text-link-hover">Lien</a>
 | ||
| ```
 | ||
| 
 | ||
| ### ⚠️ À ÉVITER
 | ||
| 
 | ||
| ```html
 | ||
| <!-- ❌ Couleurs hardcodées -->
 | ||
| <div class="bg-slate-100 text-gray-900">...</div>
 | ||
| <div class="dark:bg-gray-800">...</div>
 | ||
| 
 | ||
| <!-- ✅ Utiliser les tokens -->
 | ||
| <div class="bg-surface1 text-main">...</div>
 | ||
| ```
 | ||
| 
 | ||
| ## Tests
 | ||
| 
 | ||
| ### Checklist de validation
 | ||
| 
 | ||
| Pour chaque combinaison (14 au total) :
 | ||
| 
 | ||
| - [ ] **Sidebar** : Fond, hover, items actifs, badges
 | ||
| - [ ] **Topbar** : Barre de recherche, focus, placeholder
 | ||
| - [ ] **Liste des notes** : Items, hover, selected, path muted
 | ||
| - [ ] **Page détail** : Titres, liens, listes, blockquotes, code, tables
 | ||
| - [ ] **Mode édition** : Inputs, buttons, toolbars, CodeMirror
 | ||
| - [ ] **Panneaux** : TOC, propriétés, tags
 | ||
| - [ ] **Modales** : Fond, bordure, overlay
 | ||
| - [ ] **Menus contextuels** : Dropdown, tooltips
 | ||
| - [ ] **Toasts** : Fond, bordure, barre de progression
 | ||
| - [ ] **Tables** : Headers, zebra, hover
 | ||
| - [ ] **Chips/Tags** : Fond, texte, bordure, hover, selected
 | ||
| - [ ] **Scrollbars** : Thumb, track
 | ||
| - [ ] **Page Parameters** : Contrôles mode/thème
 | ||
| - [ ] **Mobile** : Bottom nav, sheets, drawers
 | ||
| 
 | ||
| ### Contraste
 | ||
| 
 | ||
| Tous les thèmes doivent respecter WCAG AA :
 | ||
| - Texte normal : ratio ≥ 4.5:1
 | ||
| - Texte large : ratio ≥ 3:1
 | ||
| 
 | ||
| ## Refactoring effectué
 | ||
| 
 | ||
| ### Automatisé (script `refactor-colors.mjs`)
 | ||
| 
 | ||
| - ✅ 66 fichiers mis à jour automatiquement
 | ||
| - ✅ Remplacement de 232+ occurrences de couleurs hardcodées
 | ||
| - ✅ Gestion des variantes : hover, focus, dark
 | ||
| 
 | ||
| ### Restant (109 occurrences)
 | ||
| 
 | ||
| Cas complexes nécessitant révision manuelle :
 | ||
| - Composants avec logique conditionnelle
 | ||
| - Styles inline dynamiques
 | ||
| - Cas spécifiques métier
 | ||
| 
 | ||
| ## Commandes utiles
 | ||
| 
 | ||
| ```bash
 | ||
| # Lancer le refactoring automatique
 | ||
| node scripts/refactor-colors.mjs
 | ||
| 
 | ||
| # Rechercher les couleurs hardcodées restantes
 | ||
| grep -r "bg-slate-\|bg-gray-\|text-slate-\|text-gray-" src/
 | ||
| 
 | ||
| # Lancer l'application en mode dev
 | ||
| npm run dev
 | ||
| 
 | ||
| # Tests E2E
 | ||
| npm run test:e2e
 | ||
| ```
 | ||
| 
 | ||
| ## Prochaines étapes
 | ||
| 
 | ||
| 1. ✅ Créer themes.css avec 14 variantes
 | ||
| 2. ✅ Configurer Tailwind
 | ||
| 3. ✅ Mettre à jour codemirror-themes.ts
 | ||
| 4. ✅ Refactoring automatisé (68% des couleurs)
 | ||
| 5. 🔄 Refactoring manuel des 109 occurrences restantes
 | ||
| 6. ⏳ Tests matrice complète
 | ||
| 7. ⏳ Validation contrastes
 | ||
| 8. ⏳ Documentation utilisateur
 | ||
| 
 | ||
| ## Notes techniques
 | ||
| 
 | ||
| - **Persistance** : `localStorage` clé `obsiviewer.preferences.v1`
 | ||
| - **Réactivité** : Observable `ThemeService.onPrefs$`
 | ||
| - **SSR-safe** : Vérifications `typeof window !== 'undefined'`
 | ||
| - **Performance** : Transitions CSS 150ms
 | ||
| - **Accessibilité** : `color-scheme` CSS pour scrollbars natives
 | ||
| 
 | ||
| ## Ressources
 | ||
| 
 | ||
| - [Tailwind CSS Variables](https://tailwindcss.com/docs/customizing-colors#using-css-variables)
 | ||
| - [CodeMirror 6 Theming](https://codemirror.net/docs/ref/#view.EditorView^theme)
 | ||
| - [WCAG Contrast Guidelines](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html)
 |