- 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
238 lines
6.7 KiB
Markdown
238 lines
6.7 KiB
Markdown
# 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.
|