# ๐ฏ Prompt Windsurf โ ObsiViewer Nimbus UI (Desktop + Mobile)
## ObsiViewer โ UI/UX "Nimbus-like" (simple, dense, rapide)
**Rรดle & mode :** Agis comme **Staff Frontend Engineer Angular 20 + UX designer**. Raisonnement dรฉtaillรฉ autorisรฉ. Tu as les pleins pouvoirs de refactor UI, d'ajout de composants, et de migration CSS vers Tailwind. Conserve la compatibilitรฉ de toutes features existantes.
**Contrainte majeure :** L'interface doit รชtre **100% responsive** (Desktop + Mobile). Un **bouton toggle** dans la navbar permet de basculer entre l'ancienne interface et la nouvelle sans perte d'รฉtat.
---
## Contexte rapide
* Projet : **ObsiViewer** (Angular 20 + Tailwind, Node/Express backend).
* Objectif : Refondre l'interface selon un design **Nimbus Notes**-like.
* Cลurs d'usage : navigation par **dossiers**, **tags**, **recherche**, **lecture markdown** plein รฉcran, **ToC** ร droite, **tri et filtres** rapides.
* **Nouveautรฉ** : Design adaptatif complet (Desktop/Mobile/Tablet) avec UI toggle persistรฉ.
---
## ๐ฏ Objectif final (rรฉsumรฉ)
### Desktop (โฅ1024px)
Refondre l'interface ObsiViewer en **3 colonnes** :
1. **Sidebar gauche** (Quick Links, Dossiers arborescents, Tags) โ Redimensionnable.
2. **Colonne centrale** Liste des pages (recherche, filtres dossiers/tags, tris, rรฉsultats virtualisรฉs).
3. **Vue de page** ร droite (lecture markdown, barre d'actions, **panneau sommaire/ToC** dockรฉ ร l'extrรชme droite).
Le tout **compact, performant, thรจme clair/sombre**, navigation au clavier, รฉtats persistรฉs localement.
### Mobile/Tablet (<1024px)
Une navigation **par onglets/drawer** intelligente :
- **Tab 1 : Sidebar** (dossiers, tags, recherche) โ Panneau full-width ou drawer collapsible.
- **Tab 2 : Liste** (rรฉsultats de recherche) โ Full-width scrollable.
- **Tab 3 : Page** (markdown) โ Full-width avec ToC inline collapsible ou drawer.
**Gestures** : Swipe horizontal pour navigation onglets, pull-to-refresh, tap = open item.
---
## ๐ Architecture Feature Flag & Toggle
### 1) Toggle UI dans la NavBar
Ajouter un **bouton toggle** dans `src/app/layout/app-navbar/app-navbar.component.ts` :
```html
```
### 2) Service de gestion du mode UI
Crรฉer `src/app/shared/services/ui-mode.service.ts` :
```typescript
import { Injectable, signal } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class UiModeService {
// Signal pour rรฉactivitรฉ fine-grained
isNimbusMode = signal(this.loadUIMode());
constructor() {}
toggleUIMode() {
const newMode = !this.isNimbusMode();
this.isNimbusMode.set(newMode);
localStorage.setItem('obsiviewer-ui-mode', newMode ? 'nimbus' : 'legacy');
}
private loadUIMode(): boolean {
if (typeof localStorage === 'undefined') return false;
const saved = localStorage.getItem('obsiviewer-ui-mode');
return saved ? saved === 'nimbus' : true; // Nimbus par dรฉfaut
}
}
```
### 3) Layout wrapper avec feature flag
Crรฉer `src/app/layout/app-shell-adaptive/app-shell-adaptive.component.ts` :
```typescript
import { Component, inject } from '@angular/core';
import { UiModeService } from '@app/shared/services/ui-mode.service';
import { AppShellNimbusLayoutComponent } from '../app-shell-nimbus/app-shell-nimbus.component';
import { AppShellLegacyLayoutComponent } from '../app-shell-legacy/app-shell-legacy.component';
@Component({
selector: 'app-shell-adaptive',
template: `
@if (uiMode.isNimbusMode()) {
} @else {
}
`,
standalone: true,
imports: [AppShellNimbusLayoutComponent, AppShellLegacyLayoutComponent],
})
export class AppShellAdaptiveComponent {
uiMode = inject(UiModeService);
}
```
---
## ๐จ Responsive Design Strategy
### Breakpoints Tailwind (standard)
```typescript
// tailwind.config.js
module.exports = {
theme: {
screens: {
'xs': '320px', // iPhone SE
'sm': '640px', // Petites tablettes
'md': '768px', // iPad, tablettes
'lg': '1024px', // Desktop compact
'xl': '1280px', // Desktop standard
'2xl': '1536px', // Larges รฉcrans
},
},
};
```
### Mobile First Approach
**Dรฉvelopper pour mobile d'abord, puis enrichir pour desktop.**
---
## ๐ฑ Layouts Responsifs
### Desktop Layout (โฅ1024px)
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ NAVBAR (Dark, fixed, h-14) โ
โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโค
โ โ โ โ
โ SIDEBAR โ RESULT LIST โ NOTE VIEW + TOC โ
โ (240-440px) โ (virtualized) โ (Resizable) โ
โ Resizable โ โ โ
โ โ โ โ
โ - Quick โ - Search bar โ - Markdown โ
โ Links โ - Filters โ - ToC drawer โ
โ - Folders โ - Items (80px) โ - Actions bar โ
โ - Tags โ - Pagination โ โ
โ โ โ โ
โโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโ
```
### Tablet Layout (768px โค width < 1024px)
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ NAVBAR + Toggle (fixed, h-14) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ TAB NAVIGATION (fixed, bottom) โ
โ [Sidebar] [List] [Page] [ToC] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ ACTIVE TAB CONTENT (scrollable) โ
โ - Drawer si besoin โ
โ - Full-width panels โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
### Mobile Layout (<768px)
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ NAVBAR (compact, h-12) โ
โ [Menu] [Search] [Toggle] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ TAB/DRAWER NAVIGATION โ
โ [โก] [๐] [๐] [๐] โ
โ โ
โ CONTENT AREA (Full-width) โ
โ - Drawer sidebar (80vw left) โ
โ - Swipeable list (list tab) โ
โ - Markdown full-screen (page) โ
โ - Inline ToC (toggle button) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Bottom Navigation (sticky) โ
โ Tab buttons (4 icรดnes) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
---
## ๐ฌ Composants Nimbus Responsifs
### Desktop/Mobile Variants
Chaque composant doit avoir des **variants responsifs** :
```
app-left-sidebar/
โโโ app-left-sidebar.component.ts # Logique partagรฉe
โโโ app-left-sidebar.desktop.component.ts # โฅ1024px (fixed, resizable)
โโโ app-left-sidebar.mobile.component.ts # <1024px (drawer)
app-center-list/
โโโ app-center-list.component.ts
โโโ app-center-list.desktop.component.ts # โฅ1024px (2 colonnes)
โโโ app-center-list.mobile.component.ts # <1024px (full-width)
app-note-view/
โโโ app-note-view.component.ts
โโโ app-note-view.desktop.component.ts # โฅ1024px (3 colonnes + ToC)
โโโ app-note-view.mobile.component.ts # <1024px (full-width + ToC inline)
app-toc-drawer/
โโโ app-toc-drawer.component.ts
โโโ app-toc-drawer.desktop.component.ts # โฅ1024px (Fixed right)
โโโ app-toc-drawer.mobile.component.ts # <1024px (Collapsible, inline)
```
### Dรฉtection et Injection
```typescript
// app-left-sidebar.component.ts
import { Component, inject } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
@Component({
selector: 'app-left-sidebar',
standalone: true,
template: `
@if (isDesktop$ | async) {
} @else {
}
`,
})
export class AppLeftSidebarComponent {
private breakpoint = inject(BreakpointObserver);
isDesktop$ = this.breakpoint.observe(Breakpoints.Large).pipe(
map(result => result.matches)
);
}
```
---
## ๐ฑ Navigation Mobile Avancรฉe
### Tab/Drawer Navigation
```typescript
// src/shared/services/mobile-nav.service.ts
@Injectable({ providedIn: 'root' })
export class MobileNavService {
activeTab = signal<'sidebar' | 'list' | 'page' | 'toc'>('list');
setTab(tab: 'sidebar' | 'list' | 'page' | 'toc') {
this.activeTab.set(tab);
// Persist if needed
}
}
// Usage in component
```
### Swipe Navigation (Gestures)
```typescript
// Directive pour dรฉtection de swipe
import { Directive, Output, EventEmitter, HostListener } from '@angular/core';
@Directive({
selector: '[appSwipeNav]',
standalone: true,
})
export class SwipeNavDirective {
@Output() swipeLeft = new EventEmitter();
@Output() swipeRight = new EventEmitter();
private startX = 0;
@HostListener('touchstart', ['$event'])
onTouchStart(e: TouchEvent) {
this.startX = e.touches[0].clientX;
}
@HostListener('touchend', ['$event'])
onTouchEnd(e: TouchEvent) {
const endX = e.changedTouches[0].clientX;
const diff = this.startX - endX;
if (Math.abs(diff) > 50) { // Seuil minimum
if (diff > 0) this.swipeLeft.emit();
else this.swipeRight.emit();
}
}
}
```
---
## ๐จ Composants Spรฉcifiques (Mobile-First)
### 1) Bottom Navigation (Mobile)
```html
```
### 2) Drawer Sidebar (Mobile)
```html
```
### 3) Search Bar Compact (Mobile)
```html
```
### 4) Result List Item (Mobile-Optimized)
```html
{{ item.title }}
{{ item.modified | date:'short' }}
{{ tag }}
{{ item.excerpt }}
```
### 5) Markdown Viewer (Mobile-Responsive)
```html
```
### 6) ToC Drawer (Desktop Fixed, Mobile Inline)
```typescript
// app-toc-drawer.component.ts
@Component({
selector: 'app-toc-drawer',
template: `
`,
animations: [
trigger('slideDown', [
state('in', style({ height: '*' })),
state('out', style({ height: '0px' })),
transition('in <=> out', animate('200ms ease-in-out')),
]),
],
standalone: true,
})
export class AppTocDrawerComponent {
@Input() headings: Heading[] = [];
showTocMobile = false;
isMobile$ = this.breakpoint.observe('(max-width: 1023px)').pipe(
map(r => r.matches)
);
}
```
---
## ๐ฏ Livrables Attendus
### Code
1. **Toggle UI** : `UiModeService`, bouton navbar, `AppShellAdaptiveComponent`
2. **Responsive Wrappers** : Variants pour chaque composant (Desktop/Mobile)
3. **Mobile Components** : Bottom nav, drawer sidebar, inline ToC, mobile search
4. **Gesture Handling** : Swipe navigation directive, touch-friendly interactions
5. **Breakpoint Utilities** : Service CDK layout, reactive signals
### Styling
1. **Tailwind Config** : Breakpoints personnalisรฉs, tokens tokens clair/sombre
2. **Mobile-First CSS** : Base mobile, enrichissements desktop via `md:`, `lg:`
3. **Touch-Friendly** : Boutons โฅ44x44px, padding adรฉquat, hover states
### Documentation
1. **README_UI.md** : Schรฉmas responsive, breakpoints, guide toggle
2. **MOBILE_GUIDE.md** : Navigation gestures, bottom nav flow, drawer patterns
3. **RESPONSIVE_CHECKLIST.md** : Tests par breakpoint, checklist A11y mobile
### Tests
1. **E2E** : Toggle persistence, layout switch, gesture navigation
2. **Visual Regression** : Screenshots desktop/tablet/mobile
3. **Accessibility** : Touch targets, ARIA labels, keyboard nav (Tab key)
---
## โก Performance & Mobile Optimizations
### Critical Optimizations
- **Lazy-load images** : `loading="lazy"`, responsive `srcset`
- **Virtual scroll** : CDK virtual scroll adaptรฉ mobile (item height โ 70โ80px)
- **Debounce search** : 300ms sur mobile, 150ms sur desktop
- **Avoid layout shift** : Aspect ratios, skeleton loaders
- **Network awareness** : `navigator.connection.effectiveType` pour adapt qualitรฉ
- **Battery saver** : Rรฉduire animations, throttle updates en mode saver
### Lighthouse Mobile Targets
- Performance โฅ 85
- Accessibility โฅ 95
- Best Practices โฅ 90
---
## ๐ฎ Raccourcis Clavier & Gestures
### Desktop
- `Ctrl/Cmd + K` : Palette commandes
- `Ctrl/Cmd + F` : Focus recherche
- `[` `]` : Replier/ouvrir ToC
- `Alt + โ/โ` : Navigation historique
### Mobile/Tablet
- **Tap** : Ouvrir note/item
- **Swipe left/right** : Changer onglet (list โ page โ sidebar)
- **Long-press** : Menu contextuel (favoris, open in new tab)
- **Pull-to-refresh** : Rafraรฎchir liste (optionnel)
- **Double-tap** : Zoom ToC (mobile)
---
## ๐ Critรจres d'Acceptation
### Desktop (โฅ1024px)
- [x] Layout 3 colonnes (sidebar fixe/resizable, liste, page+ToC)
- [x] Changement dossier/tag/tri reflรฉtรฉ en URL
- [x] 1000+ items fluide (60fps virtual scroll)
- [x] ToC synchronisรฉ + repliable
- [x] Tous les flux clavier-seuls possibles
### Tablet (768โ1023px)
- [x] Navigation par onglets (Sidebar / List / Page)
- [x] Drawer sidebar (80vw, swipeable)
- [x] Bottom navigation sticky (4 icรดnes)
- [x] Contenu full-width par onglet
- [x] ToC inline collapsible
### Mobile (<768px)
- [x] Drawer sidebar (80vw max)
- [x] Bottom nav (4 onglets)
- [x] Search bar compact (menu + search + filters)
- [x] List items optimisรฉs (titre + date + excerpt)
- [x] Markdown full-screen
- [x] ToC overlay ou inline toggle
- [x] Touch targets โฅ 44x44px
### Feature Flag
- [x] Toggle UI visible dans navbar
- [x] รtat persistรฉ (localStorage)
- [x] Pas de perte d'รฉtat lors du switch
- [x] Legacy UI reste intacte
### Accessibility
- [x] WCAG 2.1 AA sur tous les breakpoints
- [x] Keyboard navigation complรจte (Tab, Arrow, Enter)
- [x] ARIA labels pour navigation tactile
- [x] Focus visible partout
- [x] Zoom โค 200% sans horizontal scroll
### Performance
- [x] TTI < 2.5s cold start
- [x] Scroll 60fps sur 1000+ items
- [x] Lighthouse Mobile โฅ 85 perf, โฅ 95 a11y
- [x] ImageOptimizations (lazy, srcset, format next-gen)
---
## ๐๏ธ Arborescence Fichiers
```
src/app/
โโโ layout/
โ โโโ app-shell-adaptive/
โ โ โโโ app-shell-adaptive.component.ts # Feature flag wrapper
โ โโโ app-shell-nimbus/
โ โ โโโ app-shell-nimbus.component.ts # 3 colonnes (desktop)
โ โ โโโ app-shell-nimbus.desktop.component.ts
โ โ โโโ app-shell-nimbus.mobile.component.ts
โ โโโ app-navbar/
โ โโโ app-navbar.component.ts
โ โโโ [Bouton toggle UI intรฉgrรฉ]
โ
โโโ features/
โ โโโ sidebar/
โ โ โโโ app-left-sidebar.component.ts
โ โ โโโ app-left-sidebar.desktop.component.ts
โ โ โโโ app-left-sidebar.mobile.component.ts
โ โ
โ โโโ search-bar/
โ โ โโโ app-search-bar.component.ts
โ โ โโโ app-search-bar.desktop.component.ts
โ โ โโโ app-search-bar.mobile.component.ts
โ โ
โ โโโ result-list/
โ โ โโโ app-result-list.component.ts
โ โ โโโ app-result-list.desktop.component.ts
โ โ โโโ app-result-list.mobile.component.ts
โ โ โโโ app-result-list-item.component.ts
โ โ
โ โโโ note-view/
โ โ โโโ app-note-view.component.ts
โ โ โโโ app-note-view.desktop.component.ts
โ โ โโโ app-note-view.mobile.component.ts
โ โ
โ โโโ toc-drawer/
โ โ โโโ app-toc-drawer.component.ts
โ โ โโโ app-toc-content.component.ts
โ โ
โ โโโ bottom-nav/ [NEW]
โ โโโ app-bottom-nav.component.ts
โ โโโ app-bottom-nav.component.html
โ
โโโ shared/
โ โโโ services/
โ โ โโโ ui-mode.service.ts # [NEW] Toggle management
โ โ โโโ mobile-nav.service.ts # [NEW] Tab/drawer state
โ โ โโโ breakpoint.service.ts # [NEW] Responsive helper
โ โ
โ โโโ directives/
โ โ โโโ swipe-nav.directive.ts # [NEW] Gesture detection
โ โ
โ โโโ components/
โ โโโ resizable-handle/
โ
โโโ styles/
โโโ tokens.css # Tailwind tokens
โโโ responsive.css # Breakpoint utilities
โโโ mobile.css # Mobile-specific (touches, etc.)
```
---
## ๐
Plan d'Implรฉmentation (ordre conseillรฉ)
1. **Feature Flag Infrastructure** (1-2j)
- `UiModeService` + localStorage persistence
- `AppShellAdaptiveComponent` wrapper
- Toggle button dans navbar
2. **Responsive Shell & Breakpoints** (2-3j)
- Desktop layout 3 colonnes (>=1024px)
- Tailwind breakpoints & tokens
- Resizable sidebar logic
3. **Mobile Navigation & Bottom Nav** (2-3j)
- `BottomNavComponent` (4 onglets)
- `MobileNavService` (state management)
- Tab/drawer routing
4. **Mobile Sidebar Drawer** (1-2j)
- Drawer animรฉ (translate, backdrop)
- Swipe dismiss directive
- Z-index management
5. **Responsive Components** (3-4j)
- Search bar variants (desktop/mobile)
- Result list item responsive
- Markdown viewer mobile optimizations
6. **ToC Drawer Adaptive** (1-2j)
- Fixed right panel (desktop)
- Inline toggle (mobile)
- Animations smooth
7. **Gestures & Touch** (1-2j)
- Swipe nav directive
- Long-press menu
- Pull-to-refresh (optionnel)
8. **Accessibility & Testing** (2-3j)
- WCAG 2.1 AA audit
- Keyboard nav (Tab, Arrow)
- E2E tests (toggle, breakpoints)
- Visual regression (3 breakpoints)
**Total estimรฉ** : 13โ21 jours (รฉquipe 1 FE engineer)
---
## ๐ Scripts NPM
```bash
# Dev complet (Nimbus activรฉ par dรฉfaut)
npm run dev
# Build production
npm run build
# Tests responsifs (plusieurs breakpoints)
npm run test:responsive
# Lighthouse audit mobile
npm run audit:lighthouse:mobile
# Feature flag (override)
NIMBUS_UI=false npm run dev # Force legacy UI
```
---
## โ
Checklist Livraison
- [ ] Toggle UI visible, fonctionnel, persistรฉ
- [ ] Desktop (โฅ1024px) : 3 colonnes, interactions fluides
- [ ] Tablet (768โ1023px) : Onglets + drawer, full-width contenu
- [ ] Mobile (<768px) : Bottom nav, drawer, touch-friendly
- [ ] Tous les flux clavier-seuls rรฉalisables
- [ ] Lighthouse mobile โฅ 85 perf, โฅ 95 a11y
- [ ] Virtual scroll 60fps sur 1000+ items
- [ ] Tests E2E (toggle, breakpoints, gestures)
- [ ] Documentation complรจte (README_UI.md, MOBILE_GUIDE.md, RESPONSIVE_CHECKLIST.md)
- [ ] Zรฉro rรฉgression : legacy UI inchangรฉe, Wikilinks, bookmarks, graph intacts
- [ ] Screenshots before/after 3 breakpoints
---
## ๐ Documentation ร Produire
1. **README_UI.md** : Overview, architecture, screenshots 3 breakpoints
2. **MOBILE_GUIDE.md** : Navigation onglets, gestures, drawer patterns
3. **RESPONSIVE_CHECKLIST.md** : Tests par breakpoint, device testing
4. **DEPLOYMENT.md** : Feature flag pour bascule progressive
5. **ARCHITECTURE_DIAGRAM.md** : Schรฉmas adaptatifs (Mermaid)
---
## ๐ก Notes Importantes
- **Mobile First** : Dรฉvelopper pour mobile en premier, puis enrichir desktop.
- **Persistent State** : Le toggle UI et les filtres actifs doivent persister via localStorage (sans browser storage, utiliser sessionStorage ou service state).
- **Zero Regression** : L'ancienne interface reste intacte et fonctionnelle.
- **Performance** : Virtual scroll adaptรฉ mobile (40+ items ร l'รฉcran), lazy-load images.
- **Accessibility** : 44x44px touch targets minimum, ARIA labels complets, keyboard nav.
- **Testing** : Visual regression sur breakpoints clรฉs (375px / 768px / 1440px).
---
**Exรฉcute maintenant ce plan** : crรฉe les composants, adapte les routes/รฉtats, ajoute les styles Tailwind responsifs, branche la recherche et livre le MR conforme aux critรจres ci-dessus avec toggle UI et compatibilitรฉ 100% Desktop/Mobile.