ObsiViewer/docs/THEMING_IMPLEMENTATION.md

240 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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)