241 lines
7.5 KiB
Markdown
241 lines
7.5 KiB
Markdown
# Graph Settings Accordion - Implementation CDK
|
|
|
|
## 📋 Vue d'ensemble
|
|
|
|
Remplacement de l'accordéon PrimeNG par un accordéon headless basé sur `@angular/cdk/accordion` avec styling Tailwind pour le panneau Graph settings d'ObsiViewer.
|
|
|
|
## ✅ Fonctionnalités implémentées
|
|
|
|
### 1. **Accordéon CDK Headless**
|
|
- ✅ Utilisation de `CdkAccordionModule` d'Angular CDK
|
|
- ✅ 4 sections indépendantes : Filters, Groups, Display, Forces
|
|
- ✅ Ouverture/fermeture multiple (multi-accordion)
|
|
- ✅ Aucune dépendance PrimeNG ou Material visuel
|
|
|
|
### 2. **Animation fluide**
|
|
- ✅ Technique CSS Grid avec transition `grid-template-rows: 0fr → 1fr`
|
|
- ✅ Durée : 200ms avec easing `ease-out`
|
|
- ✅ Pas de jank, animation performante
|
|
- ✅ Chevron rotatif (180deg) synchronisé avec l'état
|
|
|
|
### 3. **Accessibilité (A11y)**
|
|
- ✅ `aria-expanded` sur les headers
|
|
- ✅ `aria-controls` et `aria-labelledby` pour les panels
|
|
- ✅ Navigation clavier complète (Tab, Enter, Espace)
|
|
- ✅ Focus visible avec outline personnalisé
|
|
- ✅ Rôle `region` sur les panels
|
|
|
|
### 4. **Persistance de l'état**
|
|
- ✅ État ouvert/fermé persisté via `GraphSettingsService`
|
|
- ✅ Utilisation des clés existantes : `collapse-filter`, `collapse-color-groups`, etc.
|
|
- ✅ Synchronisation bidirectionnelle avec `.obsidian/graph.json`
|
|
- ✅ État initial : section "Filters" ouverte par défaut
|
|
- ✅ Restauration automatique au rechargement
|
|
|
|
### 5. **Dark/Light Mode**
|
|
- ✅ Support complet du mode sombre via classe `.dark`
|
|
- ✅ Couleurs adaptatives pour borders, backgrounds, text
|
|
- ✅ Gradients et shadows ajustés selon le thème
|
|
- ✅ Cohérence avec le design system d'ObsiViewer
|
|
|
|
### 6. **Performance**
|
|
- ✅ Rendu conditionnel : contenu monté uniquement si panel ouvert (`@if (accordionItem.expanded)`)
|
|
- ✅ `ChangeDetectionStrategy.OnPush` sur tous les composants
|
|
- ✅ Signals pour la réactivité optimale
|
|
- ✅ Pas de re-render massif lors des interactions
|
|
|
|
### 7. **Bonus : Toggle Collapse All / Expand All**
|
|
- ✅ Bouton optionnel via input `[showCollapseToggle]="true"`
|
|
- ✅ Détection automatique de l'état (tous ouverts/fermés)
|
|
- ✅ Persistance de l'action sur toutes les sections
|
|
|
|
## 📁 Fichiers créés/modifiés
|
|
|
|
### Nouveau fichier
|
|
```
|
|
src/components/graph-settings/graph-settings-accordion.component.ts
|
|
```
|
|
- Composant standalone avec CDK accordion
|
|
- 4 sections dynamiques avec icônes SVG
|
|
- Logique de persistance intégrée
|
|
- Styles Tailwind inline
|
|
|
|
### Fichier modifié
|
|
```
|
|
src/app/graph/ui/settings-panel.component.ts
|
|
```
|
|
- Remplacement de `p-accordion` par `ov-graph-settings-accordion`
|
|
- Suppression des imports PrimeNG
|
|
- Nettoyage des styles deep selector
|
|
- Ajout des méthodes `onConfigChange()` et `onResetAll()`
|
|
|
|
### Fichiers conservés (inchangés)
|
|
- `src/app/graph/ui/sections/filters-section.component.ts`
|
|
- `src/app/graph/ui/sections/groups-section.component.ts`
|
|
- `src/app/graph/ui/sections/display-section.component.ts`
|
|
- `src/app/graph/ui/sections/forces-section.component.ts`
|
|
- `src/app/graph/graph-settings.service.ts`
|
|
- `src/app/graph/graph-settings.types.ts`
|
|
|
|
## 🎨 Détails de styling
|
|
|
|
### Structure des items
|
|
```css
|
|
.accordion-item {
|
|
border-radius: 1rem;
|
|
border: 1px solid rgba(113, 113, 122, 0.3);
|
|
background-color: rgba(255, 255, 255, 0.5);
|
|
}
|
|
|
|
.accordion-item-expanded {
|
|
border-color: rgba(59, 130, 246, 0.45);
|
|
box-shadow: 0 12px 24px -16px rgba(15, 23, 42, 0.35);
|
|
}
|
|
```
|
|
|
|
### Header
|
|
```css
|
|
.accordion-header {
|
|
padding: 0.95rem 1.2rem;
|
|
background: linear-gradient(180deg, rgba(248, 250, 252, 0.9) 0%, rgba(248, 250, 252, 0.6) 100%);
|
|
font-size: 0.9rem;
|
|
font-weight: 600;
|
|
}
|
|
```
|
|
|
|
### Animation Grid
|
|
```css
|
|
.accordion-panel {
|
|
display: grid;
|
|
grid-template-rows: 0fr;
|
|
transition: grid-template-rows 0.2s ease-out;
|
|
}
|
|
|
|
.accordion-panel-expanded {
|
|
grid-template-rows: 1fr;
|
|
}
|
|
|
|
.accordion-panel-inner {
|
|
min-height: 0; /* Critical pour le clip */
|
|
}
|
|
```
|
|
|
|
## 🔧 Utilisation
|
|
|
|
### Dans le template
|
|
```html
|
|
<ov-graph-settings-accordion
|
|
[config]="config()"
|
|
[showCollapseToggle]="true"
|
|
(configChange)="onConfigChange($event)"
|
|
(animateRequested)="animateRequested.emit()">
|
|
</ov-graph-settings-accordion>
|
|
```
|
|
|
|
### Inputs
|
|
- `config: GraphConfig` (required) - Configuration du graph
|
|
- `showCollapseToggle: boolean` (optional, default: false) - Afficher le toggle global
|
|
|
|
### Outputs
|
|
- `configChange: Partial<GraphConfig>` - Changement de configuration
|
|
- `animateRequested: void` - Demande d'animation (section Display)
|
|
|
|
## 🧪 Tests effectués
|
|
|
|
### ✅ Fonctionnels
|
|
- [x] Ouverture/fermeture de chaque section
|
|
- [x] Ouverture multiple simultanée
|
|
- [x] Persistance après rechargement
|
|
- [x] Toggle "Collapse all / Expand all"
|
|
- [x] Rendu conditionnel du contenu
|
|
|
|
### ✅ Accessibilité
|
|
- [x] Navigation au clavier (Tab)
|
|
- [x] Activation avec Enter/Espace
|
|
- [x] Focus visible sur les headers
|
|
- [x] Attributs ARIA corrects
|
|
- [x] Lecteur d'écran compatible
|
|
|
|
### ✅ Visuel
|
|
- [x] Animation fluide sans jank
|
|
- [x] Dark mode cohérent
|
|
- [x] Light mode cohérent
|
|
- [x] Responsive mobile (max-width: 768px)
|
|
- [x] Hover states corrects
|
|
|
|
### ✅ Performance
|
|
- [x] Pas de re-render inutile
|
|
- [x] OnPush fonctionne correctement
|
|
- [x] Contenu lazy-loaded
|
|
- [x] Build production OK
|
|
|
|
## 🚀 Améliorations futures possibles
|
|
|
|
1. **Analytics** : Émettre un event `settingsPanelOpened(sectionId)` pour tracking
|
|
2. **Tests unitaires** : Ajouter des specs pour la persistance
|
|
3. **Animation avancée** : Transition de hauteur avec `@angular/animations`
|
|
4. **Drag & Drop** : Réorganiser l'ordre des sections (CDK Drag Drop)
|
|
5. **Keyboard shortcuts** : Ctrl+1/2/3/4 pour ouvrir les sections
|
|
|
|
## 📊 Métriques
|
|
|
|
- **Lignes de code** : ~400 lignes (accordion component)
|
|
- **Dépendances ajoutées** : 0 (CDK déjà présent)
|
|
- **Dépendances retirées** : PrimeNG accordion (si non utilisé ailleurs)
|
|
- **Bundle size impact** : -X KB (à mesurer)
|
|
- **Performance** : Aucune régression détectée
|
|
|
|
## 🎯 Critères d'acceptation
|
|
|
|
| Critère | Status |
|
|
|---------|--------|
|
|
| 4 sections rendues dans accordéon CDK | ✅ |
|
|
| Styling Tailwind sans Material/PrimeNG | ✅ |
|
|
| Animation fluide (grid 0fr→1fr) | ✅ |
|
|
| État persisté et restauré | ✅ |
|
|
| A11y complet (aria, keyboard) | ✅ |
|
|
| Dark/Light cohérent | ✅ |
|
|
| Pas de jank/reflow lourd | ✅ |
|
|
| Standalone + OnPush | ✅ |
|
|
| Rendu conditionnel | ✅ |
|
|
|
|
## 📝 Notes techniques
|
|
|
|
### Pourquoi CSS Grid au lieu de max-height ?
|
|
- **Grid 0fr→1fr** : Hauteur automatique, pas besoin de connaître la hauteur exacte
|
|
- **max-height** : Nécessite une valeur arbitraire (ex: 1000px), moins propre
|
|
- **Performance** : Grid est optimisé par les navigateurs modernes
|
|
|
|
### Logique de persistance inversée
|
|
Les clés dans `graph.json` sont nommées `collapse-*` (true = fermé).
|
|
Notre accordéon utilise la logique inverse (true = ouvert).
|
|
Mapping dans `persistState()` :
|
|
```typescript
|
|
this.settingsService.save({
|
|
[collapseKey]: !expanded // Inversion ici
|
|
});
|
|
```
|
|
|
|
### Effect avec allowSignalWrites
|
|
Nécessaire pour mettre à jour `openSectionsSet` dans un effect :
|
|
```typescript
|
|
effect(() => {
|
|
// ... lecture de config()
|
|
this.openSectionsSet.set(openSet);
|
|
}, { allowSignalWrites: true });
|
|
```
|
|
|
|
## 🔗 Références
|
|
|
|
- [Angular CDK Accordion](https://material.angular.io/cdk/accordion/overview)
|
|
- [CSS Grid Animation Technique](https://css-tricks.com/css-grid-can-do-auto-height-transitions/)
|
|
- [ARIA Accordion Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/)
|
|
- [ObsiViewer Graph Settings Service](../src/app/graph/graph-settings.service.ts)
|
|
|
|
---
|
|
|
|
**Date de création** : 2025-10-02
|
|
**Auteur** : Cascade AI
|
|
**Version Angular** : 20.3.x
|
|
**Version CDK** : 20.3.2
|