ObsiViewer/docs/MIGRATION_INLINE_TOOLBAR.md
Bruno Charest ee3085ce38 feat: add Nimbus Editor with Unsplash integration
- Integrated Unsplash API for image search functionality with environment configuration
- Added new Nimbus Editor page component with navigation from sidebar and mobile drawer
- Enhanced TOC with highlight animation for editor heading navigation
- Improved CDK overlay z-index hierarchy for proper menu layering
- Removed obsolete logging validation script
2025-11-11 11:38:27 -05:00

238 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.

# Guide de migration - Toolbar fixe → Toolbar inline
## 📌 Résumé des changements
### Avant (Toolbar fixe)
```
┌─────────────────────────────────────────┐
│ [Titre du document] │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ Start writing... [🤖][☑][1.][•][⊞]│ │ ← Barre fixe
│ └─────────────────────────────────────┘ │
│ │
│ Bloc 1: Paragraphe │
│ Bloc 2: Table │
│ Bloc 3: Image │
└─────────────────────────────────────────┘
```
### Après (Toolbar inline)
```
┌─────────────────────────────────────────┐
│ [Titre du document] │
│ │
│ ⋮⋮ Start writing... [🤖][☑][1.][⊞][⬇] │ ← Inline dans le bloc
│ │
│ ⋮⋮ Bloc 1: Paragraphe [icônes...] │ ← Chaque bloc a sa toolbar
│ ⋮⋮ Bloc 2: Table [icônes...] │
│ ⋮⋮ Bloc 3: Image [icônes...] │
└─────────────────────────────────────────┘
```
## 🔄 Composants modifiés
### 1. EditorShellComponent
**Supprimé**:
```typescript
// ❌ ANCIEN - Toolbar fixe au niveau shell
<div class="mb-4">
<app-editor-toolbar (action)="onToolbarAction($event)" />
</div>
```
**Résultat**: Plus de toolbar globale, chaque bloc gère la sienne.
### 2. ParagraphBlockComponent
**Avant**:
```html
<div
contenteditable="true"
placeholder="Start writing or type '/', '@'"
></div>
```
**Après**:
```html
<div (mouseenter)="isHovered.set(true)" (mouseleave)="isHovered.set(false)">
<app-block-inline-toolbar
[isFocused]="isFocused"
[isHovered]="isHovered"
(action)="onToolbarAction($event)"
>
<div
contenteditable="true"
(focus)="isFocused.set(true)"
(blur)="isFocused.set(false)"
></div>
</app-block-inline-toolbar>
</div>
```
**Changements**:
- ✅ Wrapper avec gestion hover/focus
- ✅ Intégration `BlockInlineToolbarComponent`
- ✅ Signals pour états visuels
- ✅ Détection "/" pour menu
### 3. BlockMenuComponent
**Avant**:
```typescript
// Position fixe centrée
style="top: 20%; left: 50%; transform: translateX(-50%)"
width: 680px
height: 600px
```
**Après**:
```typescript
// Position contextuelle près du curseur
[style.top.px]="menuPosition().top"
[style.left.px]="menuPosition().left"
width: 420px
height: 500px
```
**Changements**:
- ✅ Taille réduite (420×500 vs 680×600)
- ✅ Position dynamique basée sur bloc actif
- ✅ Design compact (spacing réduit)
- ✅ Headers sticky optimisés
## 📝 Checklist de migration pour autres blocs
Pour migrer un autre type de bloc (heading, list, table, etc.):
### ✅ Étape 1: Imports
```typescript
import { signal } from '@angular/core';
import { BlockInlineToolbarComponent } from '../block-inline-toolbar.component';
import { PaletteService } from '../../../services/palette.service';
@Component({
imports: [..., BlockInlineToolbarComponent],
})
```
### ✅ Étape 2: Ajouter les signals
```typescript
export class YourBlockComponent {
isFocused = signal(false);
isHovered = signal(false);
private paletteService = inject(PaletteService);
}
```
### ✅ Étape 3: Wrapper le template
```html
<div
(mouseenter)="isHovered.set(true)"
(mouseleave)="isHovered.set(false)"
>
<app-block-inline-toolbar
[isFocused]="isFocused"
[isHovered]="isHovered"
(action)="onToolbarAction($event)"
>
<!-- Votre contenu existant -->
</app-block-inline-toolbar>
</div>
```
### ✅ Étape 4: Gérer focus/blur
```html
<!-- Dans votre élément éditable -->
<div
contenteditable="true"
(focus)="isFocused.set(true)"
(blur)="isFocused.set(false)"
>
```
### ✅ Étape 5: Implémenter onToolbarAction
```typescript
onToolbarAction(action: string): void {
if (action === 'more' || action === 'menu') {
this.paletteService.open();
} else {
// Logique spécifique au bloc
this.handleQuickAction(action);
}
}
```
## 🎯 Nouveaux comportements
### Détection du "/"
```typescript
onKeyDown(event: KeyboardEvent): void {
if (event.key === '/') {
const text = (event.target as HTMLElement).textContent || '';
if (text.length === 0 || text.endsWith(' ')) {
event.preventDefault();
this.paletteService.open(); // Ouvre le menu
}
}
}
```
### États visuels
| État | Drag handle | Icônes | Background |
|------|-------------|--------|------------|
| Défaut | Caché | Cachées | Transparent |
| Hover | Visible | Semi-visibles | `bg-neutral-800/30` |
| Focus | Visible | Visibles | Transparent |
## 🐛 Points d'attention
### 1. Z-index et layering
- Drag handle: `absolute -left-8` (en dehors du flux)
- Menu: `z-[9999]` (au dessus de tout)
- Sticky headers: `z-10` (dans le menu)
### 2. Responsive
Le drag handle peut déborder sur mobile. Considérer:
```css
@media (max-width: 640px) {
.drag-handle {
position: relative;
left: 0;
}
}
```
### 3. Performance
Les signals sont efficients, mais éviter:
```typescript
// ❌ MAUVAIS - Recalcul à chaque render
[isFocused]="someComplexComputation()"
// ✅ BON - Signal mis à jour explicitement
[isFocused]="isFocused"
```
## 📊 Comparaison des fichiers
| Fichier | Avant | Après | Statut |
|---------|-------|-------|--------|
| `editor-toolbar.component.ts` | Toolbar globale | N/A | ⚠️ Peut être supprimé |
| `block-inline-toolbar.component.ts` | N/A | Toolbar par bloc | ✅ Nouveau |
| `paragraph-block.component.ts` | Simple contenteditable | Wrapper + toolbar | ✅ Migré |
| `block-menu.component.ts` | Position fixe centrée | Position contextuelle | ✅ Optimisé |
| `editor-shell.component.ts` | Contient toolbar | Seulement blocks | ✅ Simplifié |
## 🔮 Prochaines étapes
1. **Migrer les autres blocs** (heading, list, table, etc.)
2. **Implémenter le drag & drop** via le drag handle
3. **Menu bloc contextuel** (clic sur ⋮⋮)
4. **Toolbar flottante** pour formatage texte (Bold, Italic, etc.)
5. **Tests E2E** pour valider les interactions
---
**Note**: L'ancien `EditorToolbarComponent` peut être conservé temporairement pour référence, mais n'est plus utilisé dans le shell.