feat: add bookmark view modes (card/tile/cover) and enhance button block with visual config modal - Added three view modes for bookmark blocks: card (default with side image), tile (compact horizontal), and cover (large top image) - Implemented view mode submenu in block context menu with visual indicators for active mode - Enhanced bookmark favicon handling with fallback logic and error state tracking - Refactored button block with inline visual editor replacing text inputs - Created Button
292 lines
8.7 KiB
Markdown
292 lines
8.7 KiB
Markdown
# URL Paste Menu & Button Configuration - Documentation
|
|
|
|
## 📋 Vue d'ensemble
|
|
|
|
Cette fonctionnalité ajoute deux nouvelles capacités à l'éditeur Nimbus :
|
|
|
|
1. **Menu de collage d'URL** : Lorsqu'un utilisateur colle une URL dans un bloc paragraphe, un menu contextuel apparaît avec plusieurs options de transformation
|
|
2. **Configuration avancée des boutons** : Un modal de configuration complet pour personnaliser les blocs boutons
|
|
|
|
## 🎯 Fonctionnalités implémentées
|
|
|
|
### 1. Menu de collage d'URL (UrlPasteMenu)
|
|
|
|
Lorsqu'une URL est collée dans un bloc paragraphe en mode prompt, un menu s'affiche avec 5 options :
|
|
|
|
#### Options disponibles :
|
|
- **URL** : Affiche l'URL brute dans le bloc paragraphe
|
|
- **Titre** : Récupère le titre du site web et l'affiche dans le paragraphe
|
|
- **Intégrer** : Convertit le bloc en `embed-block` pour afficher la page dans une iframe ajustable
|
|
- **Marque-page** : Convertit le bloc en `bookmark-block` avec preview de la page
|
|
- **Bouton** : Convertit le bloc en `button-block` avec l'URL configurée
|
|
|
|
#### Comportement :
|
|
- Détection automatique des URLs (regex `https?://...`)
|
|
- Menu positionné près du curseur
|
|
- Récupération asynchrone du titre via `UrlPreviewService`
|
|
- Fermeture automatique après sélection
|
|
|
|
### 2. Configuration avancée des boutons (ButtonConfigModal)
|
|
|
|
Un modal complet pour configurer tous les aspects d'un bouton :
|
|
|
|
#### Paramètres configurables :
|
|
|
|
**Texte et URL**
|
|
- Titre du bouton (label)
|
|
- URL ou Email de destination
|
|
- ID unique du bouton (affiché, non modifiable)
|
|
|
|
**Comportement**
|
|
- ☑️ Ouvrir dans un nouvel onglet
|
|
|
|
**Forme du bouton**
|
|
- 🔵 Pill (arrondi complet)
|
|
- ⬜ Rounded (coins arrondis)
|
|
|
|
**Couleur d'arrière-plan**
|
|
- Palette de 7 couleurs prédéfinies :
|
|
- Bleu (#3b82f6)
|
|
- Rouge (#ef4444)
|
|
- Orange (#f59e0b)
|
|
- Vert (#10b981)
|
|
- Violet (#8b5cf6)
|
|
- Rose (#ec4899)
|
|
- Gris (#6b7280)
|
|
|
|
**Taille**
|
|
- Petit (small)
|
|
- Moyen (medium) - par défaut
|
|
- Grand (large)
|
|
|
|
**Type de bouton**
|
|
- ⚪ Bouton 3D (effet de profondeur avec border-bottom)
|
|
- ⚪ Bouton avec ombre (shadow + hover effect)
|
|
- ⚪ Par défaut (style simple)
|
|
|
|
#### Comportement du modal :
|
|
- Ouverture automatique lors de la création d'un nouveau bouton
|
|
- Bouton d'édition (crayon) visible au survol du bouton
|
|
- Boutons "Annuler" et "Terminé"
|
|
- Validation en temps réel
|
|
|
|
## 📁 Fichiers créés
|
|
|
|
### Composants
|
|
|
|
1. **`src/app/editor/components/block/url-paste-menu.component.ts`**
|
|
- Composant standalone Angular
|
|
- Affiche le menu contextuel lors du collage d'URL
|
|
- Récupère le titre du site via `UrlPreviewService`
|
|
- Émet l'action sélectionnée vers le parent
|
|
|
|
2. **`src/app/editor/components/block/blocks/button-config-modal.component.ts`**
|
|
- Modal de configuration des boutons
|
|
- Interface complète avec tous les paramètres
|
|
- Utilise Angular Signals pour la réactivité
|
|
- Design cohérent avec le reste de l'application
|
|
|
|
### Modifications
|
|
|
|
3. **`src/app/editor/components/block/blocks/paragraph-block.component.ts`**
|
|
- Ajout de l'import `UrlPasteMenuComponent`
|
|
- Ajout de la méthode `onPaste()` pour intercepter le collage
|
|
- Ajout de la méthode `onPasteMenuAction()` pour gérer les actions
|
|
- Ajout des signaux : `pasteMenuVisible`, `pastedUrl`, `pasteMenuPosition`
|
|
- Détection d'URL via regex
|
|
- Conversion de blocs selon l'action choisie
|
|
|
|
4. **`src/app/editor/components/block/blocks/button-block.component.ts`**
|
|
- Refonte complète du composant
|
|
- Ajout de l'import `ButtonConfigModalComponent`
|
|
- Rendu visuel du bouton avec tous les styles
|
|
- Ouverture automatique du modal si le bouton est vide
|
|
- Bouton d'édition au survol
|
|
- Méthodes : `getButtonClasses()`, `getBgColor()`, `getTextColor()`
|
|
|
|
5. **`src/app/editor/core/models/block.model.ts`**
|
|
- Extension de l'interface `ButtonProps` :
|
|
```typescript
|
|
export interface ButtonProps {
|
|
label: string;
|
|
url: string;
|
|
variant?: 'primary' | 'secondary' | 'outline' | '3d' | 'shadow' | 'default';
|
|
openInNewTab?: boolean;
|
|
shape?: 'pill' | 'rounded' | 'square';
|
|
backgroundColor?: string;
|
|
size?: 'small' | 'medium' | 'large';
|
|
}
|
|
```
|
|
|
|
## 🔄 Flux d'utilisation
|
|
|
|
### Scénario 1 : Collage d'URL
|
|
|
|
```
|
|
1. Utilisateur colle une URL (Ctrl+V) dans un paragraphe vide
|
|
↓
|
|
2. ParagraphBlockComponent.onPaste() détecte l'URL
|
|
↓
|
|
3. UrlPasteMenu s'affiche avec 5 options
|
|
↓
|
|
4. Utilisateur clique sur une option (ex: "Bouton")
|
|
↓
|
|
5. ParagraphBlockComponent.onPasteMenuAction() convertit le bloc
|
|
↓
|
|
6. Le bloc devient un ButtonBlock
|
|
↓
|
|
7. ButtonConfigModal s'ouvre automatiquement (label vide)
|
|
↓
|
|
8. Utilisateur configure le bouton
|
|
↓
|
|
9. Clic sur "Terminé" → bouton créé et stylisé
|
|
```
|
|
|
|
### Scénario 2 : Création directe de bouton
|
|
|
|
```
|
|
1. Utilisateur crée un bloc bouton via le menu "/"
|
|
↓
|
|
2. ButtonBlock créé avec props par défaut
|
|
↓
|
|
3. ButtonConfigModal s'ouvre automatiquement
|
|
↓
|
|
4. Utilisateur configure tous les paramètres
|
|
↓
|
|
5. Clic sur "Terminé" → bouton créé
|
|
```
|
|
|
|
### Scénario 3 : Édition d'un bouton existant
|
|
|
|
```
|
|
1. Utilisateur survole un bouton existant
|
|
↓
|
|
2. Icône crayon apparaît en haut à droite
|
|
↓
|
|
3. Clic sur l'icône
|
|
↓
|
|
4. ButtonConfigModal s'ouvre avec les valeurs actuelles
|
|
↓
|
|
5. Modifications et "Terminé"
|
|
↓
|
|
6. Bouton mis à jour
|
|
```
|
|
|
|
## 🎨 Styles CSS appliqués
|
|
|
|
### Classes dynamiques du bouton
|
|
|
|
**Taille** :
|
|
- `small` : `px-3 py-1.5 text-xs`
|
|
- `medium` : `px-4 py-2 text-sm`
|
|
- `large` : `px-6 py-3 text-base`
|
|
|
|
**Forme** :
|
|
- `pill` : `rounded-full`
|
|
- `rounded` : `rounded-lg`
|
|
- `square` : `rounded-md`
|
|
|
|
**Variant** :
|
|
- `3d` : `border-b-4 border-black/20 active:border-b-0 active:translate-y-1`
|
|
- `shadow` : `shadow-lg hover:shadow-xl hover:-translate-y-0.5`
|
|
- `outline` : `border-2` (fond transparent, texte coloré)
|
|
|
|
## 🔧 Intégration technique
|
|
|
|
### Dépendances
|
|
|
|
- `UrlPreviewService` : Pour récupérer les métadonnées des URLs
|
|
- `DocumentService` : Pour convertir les blocs
|
|
- `Angular Signals` : Pour la réactivité
|
|
- `CommonModule`, `FormsModule` : Modules Angular standard
|
|
|
|
### Détection d'URL
|
|
|
|
Regex utilisée :
|
|
```typescript
|
|
/^https?:\/\/[^\s/$.?#].[^\s]*$/i
|
|
```
|
|
|
|
Cette regex détecte :
|
|
- Protocole `http://` ou `https://`
|
|
- Domaine valide
|
|
- Chemin optionnel
|
|
- Pas d'espaces
|
|
|
|
### Conversion de blocs
|
|
|
|
Utilise `DocumentService.updateBlock()` pour transformer le bloc paragraphe en :
|
|
- `embed` : `{ url, provider: 'generic' }`
|
|
- `bookmark` : `{ url, title, viewMode: 'card' }`
|
|
- `button` : `{ label, url, variant: 'primary' }`
|
|
|
|
## ✅ Tests recommandés
|
|
|
|
### Test 1 : Menu URL
|
|
1. Ouvrir l'éditeur Nimbus
|
|
2. Créer un nouveau paragraphe
|
|
3. Coller `https://example.com`
|
|
4. Vérifier que le menu apparaît
|
|
5. Tester chaque option
|
|
|
|
### Test 2 : Configuration bouton
|
|
1. Créer un bouton via "/"
|
|
2. Vérifier l'ouverture du modal
|
|
3. Modifier tous les paramètres
|
|
4. Vérifier le rendu visuel
|
|
|
|
### Test 3 : Édition bouton
|
|
1. Créer un bouton
|
|
2. Survoler le bouton
|
|
3. Cliquer sur l'icône crayon
|
|
4. Modifier et sauvegarder
|
|
|
|
### Test 4 : URLs complexes
|
|
- URL avec paramètres : `https://example.com?param=value`
|
|
- URL avec ancre : `https://example.com#section`
|
|
- URL avec port : `http://localhost:3000`
|
|
|
|
## 🐛 Gestion des erreurs
|
|
|
|
- Si `UrlPreviewService` échoue, le titre reste vide (pas de blocage)
|
|
- Si l'URL est invalide, le menu ne s'affiche pas
|
|
- Si le modal est annulé, aucune modification n'est appliquée
|
|
- Prévention de navigation dans l'éditeur (click intercepté)
|
|
|
|
## 🚀 Améliorations futures possibles
|
|
|
|
1. **Menu URL** :
|
|
- Support des URLs sans protocole (auto-ajout de `https://`)
|
|
- Prévisualisation de l'embed avant conversion
|
|
- Historique des URLs récentes
|
|
|
|
2. **Configuration bouton** :
|
|
- Sélecteur de couleur personnalisé (color picker)
|
|
- Prévisualisation en temps réel dans le modal
|
|
- Templates de boutons prédéfinis
|
|
- Support des icônes (Lucide, FontAwesome)
|
|
|
|
3. **Général** :
|
|
- Raccourcis clavier pour le menu URL
|
|
- Drag & drop d'URLs depuis le navigateur
|
|
- Support des emails (mailto:)
|
|
- Support des numéros de téléphone (tel:)
|
|
|
|
## 📝 Notes de développement
|
|
|
|
- Tous les composants sont **standalone** (pas de module requis)
|
|
- Utilisation de **Angular Signals** pour la réactivité moderne
|
|
- **TailwindCSS** pour tous les styles
|
|
- **z-index: 12000** pour le modal (au-dessus de tout)
|
|
- **z-index: 11000** pour le menu URL
|
|
- Pas de dépendances externes supplémentaires
|
|
|
|
## ✨ Résumé
|
|
|
|
Cette implémentation ajoute une expérience utilisateur fluide et moderne pour :
|
|
- Transformer rapidement des URLs collées en différents types de blocs
|
|
- Configurer finement l'apparence et le comportement des boutons
|
|
- Maintenir la cohérence visuelle avec le reste de l'éditeur Nimbus
|
|
|
|
Tous les fichiers sont prêts et fonctionnels. La fonctionnalité est complète et prête pour les tests.
|