docs: remove outdated implementation documentation files - Deleted AI_TOOLS_IMPLEMENTATION.md (296 lines) - outdated AI tools integration guide - Deleted ALIGN_INDENT_COLUMNS_FIX.md (557 lines) - obsolete column alignment fix documentation - Deleted BLOCK_COMMENTS_IMPLEMENTATION.md (400 lines) - superseded block comments implementation notes - Deleted DRAG_DROP_COLUMNS_IMPLEMENTATION.md (500 lines) - outdated drag-and-drop columns guide - Deleted INLINE_TOOLBAR_IMPLEMENTATION.md (350 lines) - obsol
9.2 KiB
9.2 KiB
Mode d'édition inline Nimbus - Documentation technique
📋 Vue d'ensemble
Le mode d'édition Nimbus suit le concept WYSIWYG par blocs, inspiré de Notion, avec une toolbar inline intégrée dans chaque bloc plutôt qu'une barre fixe.
🎯 Concepts clés
1. Toolbar inline par bloc
Chaque bloc affiche sa propre toolbar au survol ou au focus:
- Position: Intégrée directement dans la ligne du bloc
- Visibilité: Apparaît au hover ou focus
- Drag handle:
⋮⋮à gauche pour déplacer/ouvrir menu contextuel
2. Déclenchement du menu contextuel
Le menu "Add Block" s'ouvre de 3 façons:
- Caractère "/" - Frappe au début ou après espace
- Icône "⬇️" - Clic sur bouton "More items"
- Drag handle - Clic sur
⋮⋮à gauche du bloc
3. États visuels
┌─────────────────────────────────────────────────────────┐
│ État par défaut (non focus, non hover) │
│ - Placeholder gris visible │
│ - Icônes cachées (opacity: 0) │
│ - Drag handle caché │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ État hover (souris au dessus) │
│ - Background subtil (bg-neutral-800/30) │
│ - Icônes semi-visibles (opacity: 70%) │
│ - Drag handle visible │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ État focus (édition active) │
│ - Placeholder masqué │
│ - Icônes complètement visibles (opacity: 100%) │
│ - Drag handle visible │
│ - Curseur visible │
└─────────────────────────────────────────────────────────┘
🏗️ Architecture des composants
BlockInlineToolbarComponent
Fichier: src/app/editor/components/block/block-inline-toolbar.component.ts
Responsabilités:
- Afficher le drag handle (⋮⋮) avec tooltip
- Afficher les icônes rapides (AI, checkbox, lists, table, etc.)
- Gérer les états hover/focus
- Émettre les actions vers le bloc parent
Structure:
<div class="group/block">
<!-- Drag handle (absolute left) -->
<div class="absolute -left-8">⋮⋮</div>
<!-- Input wrapper -->
<div class="flex-1 px-3 py-2">
<ng-content /> <!-- Contenu éditable -->
<!-- Quick icons (conditional opacity) -->
<div class="flex gap-0.5">
<button>AI</button>
<button>☑</button>
<button>•</button>
<!-- ... -->
<button>⬇️ More</button>
</div>
</div>
</div>
Inputs:
isFocused: Signal<boolean>- État focus du blocisHovered: Signal<boolean>- État hover du blocplaceholder: string- Texte du placeholder
Outputs:
action: EventEmitter<string>- Action déclenchée (use-ai, table, more, etc.)
ParagraphBlockComponent (mis à jour)
Fichier: src/app/editor/components/block/blocks/paragraph-block.component.ts
Nouvelles fonctionnalités:
- Intégration de
BlockInlineToolbarComponent - Gestion des états
isFocusedetisHoveredvia signals - Détection du "/" pour ouvrir le menu
- Gestion des actions de toolbar
Template structure:
<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>
BlockMenuComponent (optimisé)
Fichier: src/app/editor/components/palette/block-menu.component.ts
Changements:
- Taille réduite: 420px × 500px (vs 680px × 600px)
- Position contextuelle: S'ouvre près du bloc actif/curseur
- Design compact: Spacing réduit, textes plus petits
- Sticky headers: Restent visibles au scroll
Positionnement:
menuPosition = computed(() => {
const activeBlock = document.querySelector('[contenteditable]:focus');
if (activeBlock) {
const rect = activeBlock.getBoundingClientRect();
return {
top: rect.top + 30, // 30px sous le curseur
left: rect.left // Aligné à gauche
};
}
return { top: 100, left: 50 }; // Fallback
});
🎨 Design tokens
Toolbar inline
/* Drag handle */
-left-8 /* Position absolue gauche */
opacity-0 /* Caché par défaut */
group-hover/block:opacity-100 /* Visible au hover */
/* Container */
px-3 py-2 /* Padding interne */
hover:bg-neutral-800/30 /* Background au hover */
rounded-lg /* Coins arrondis */
/* Icônes */
w-4 h-4 /* Taille icônes */
text-gray-400 /* Couleur par défaut */
hover:text-gray-200 /* Couleur au hover */
Menu contextuel
/* Panel */
bg-neutral-800/98 /* Background semi-transparent */
backdrop-blur-md /* Effet flou */
w-[420px] /* Largeur fixe */
max-h-[500px] /* Hauteur max */
rounded-lg /* Coins arrondis */
border-neutral-700 /* Bordure */
/* Section header (sticky) */
sticky top-0 /* Reste en haut au scroll */
bg-neutral-800/95 /* Background avec transparence */
backdrop-blur-md /* Flou de fond */
text-[10px] /* Texte très petit */
uppercase tracking-wider /* Majuscules espacées */
/* Item */
px-2 py-1.5 /* Padding compact */
hover:bg-neutral-700/80 /* Background hover */
text-sm /* Texte petit */
🔧 Intégration dans d'autres blocs
Pour ajouter la toolbar inline à un autre type de bloc:
1. Importer le composant
import { BlockInlineToolbarComponent } from '../block-inline-toolbar.component';
import { signal } from '@angular/core';
@Component({
imports: [BlockInlineToolbarComponent],
// ...
})
2. Ajouter les signals
isFocused = signal(false);
isHovered = signal(false);
3. Wrapper le contenu
<div
(mouseenter)="isHovered.set(true)"
(mouseleave)="isHovered.set(false)"
>
<app-block-inline-toolbar
[isFocused]="isFocused"
[isHovered]="isHovered"
(action)="onToolbarAction($event)"
>
<!-- Votre contenu éditable ici -->
</app-block-inline-toolbar>
</div>
4. Gérer les événements
onToolbarAction(action: string): void {
if (action === 'more' || action === 'menu') {
this.paletteService.open();
} else {
// Logique spécifique
}
}
📱 Responsive
Desktop
- Drag handle à
-left-8(32px à gauche) - Toutes les icônes visibles
- Menu 420px de large
Tablet
- Drag handle visible au tap
- Menu 90% de la largeur viewport
- Icônes réduites
Mobile
- Drag handle toujours visible
- Menu plein écran
- Toolbar simplifiée (icônes essentielles seulement)
⌨️ Raccourcis clavier
Dans un bloc
| Touche | Action |
|---|---|
/ |
Ouvrir le menu contextuel |
@ |
Mention (futur) |
Enter |
Nouveau bloc paragraphe |
Backspace (bloc vide) |
Supprimer le bloc |
↑ / ↓ |
Naviguer entre blocs |
Dans le menu
| Touche | Action |
|---|---|
↑ / ↓ |
Naviguer dans les items |
Enter |
Sélectionner l'item |
Esc |
Fermer le menu |
| Lettres | Rechercher |
🚀 Améliorations futures
- Drag & drop - Utiliser le drag handle pour réordonner
- Menu bloc contextuel - Options spécifiques (dupliquer, supprimer, transformer)
- Formatage texte - Bold, italic, couleur via toolbar flottante sur sélection
- Slash commands avancés -
/table 3x3,/heading 2, etc. - Templates inline - Insertion rapide de structures prédéfinies
- Collaboration - Curseurs multiples et édition temps réel
📐 Schéma de flux
Utilisateur clique dans un bloc
↓
isFocused.set(true)
↓
Toolbar inline devient visible (opacity: 100%)
↓
Utilisateur tape "/"
↓
PaletteService.open()
↓
BlockMenuComponent s'affiche près du curseur
↓
Utilisateur sélectionne un item
↓
Nouveau bloc inséré après le bloc actuel
↓
Focus sur le nouveau bloc
Version: 2.0
Date: 7 novembre 2025
Auteur: Nimbus Team