refactor(BlockEditor): add BlockInsertMenu component and unify block type icon styling

- introduce `BlockInsertMenu` dropdown to insert a new block after the current one
- extract `TYPE_ICON_BOX_CLASS` constant shared between insert menu and transform menu
- align `BlockActionsMenu` transform list item padding/gap to match new insert menu style
- update README to document the new insert menu behaviour and enabled blocks filtering
This commit is contained in:
2026-04-25 20:46:45 -04:00
parent 56767cff0f
commit e928e5317c
3 changed files with 129 additions and 36 deletions
+16 -14
View File
@@ -148,26 +148,26 @@ En mode sélection multi-blocs :
- frappe d'un caractère imprimable → remplace les blocs sélectionnés par un nouveau paragraphe contenant ce caractère
- clic dans l'éditeur → quitte la sélection
## Drag and drop
## Poignées au survol
Chaque bloc affiche au survol :
- une poignée `Add01Icon` pour insérer un bloc en dessous (ouvre le slash menu)
- une poignée `DragDropVerticalIcon` à double rôle : presser-glisser pour réordonner, simple clic pour ouvrir le menu d'actions du bloc
Chaque bloc affiche au survol deux boutons à gauche, chacun ouvrant un
dropdown manuel (state local + fermeture sur clic extérieur / `Escape`) :
- `Add01Icon` (« + ») — ouvre le **menu d'insertion** : liste tous les types
disponibles (filtrés par `enabledBlocks`) avec une icône en boîte. Le clic
sur un type insère le bloc juste en dessous du bloc courant.
- `DragDropVerticalIcon` — double rôle : presser-glisser pour réordonner
(drag-and-drop HTML5 natif), simple clic pour ouvrir le **menu d'actions**.
Les icônes proviennent de [`src/shared/icons/index.js`](../../icons/index.js).
Le drag-and-drop utilise l'API HTML5 native, pas de dépendance externe.
## Menu d'actions du bloc
Un clic sur la poignée `DragDropVerticalIcon` ouvre un menu déroulant
(`@headlessui/react`) contenant :
- **Transformer ▸** — sous-menu qui s'ouvre au survol, listant les types de
blocs texte disponibles (paragraphe, titres 1 à 6, listes, citation, code).
Cliquer sur un type remplace le bloc courant en conservant son contenu
inline et ferme le menu. L'item est masqué pour les blocs non-texte (image,
séparateur). Le filtrage respecte la prop `enabledBlocks`.
blocs texte disponibles (paragraphe, titres 1 à 6, listes, citation, code)
avec une icône en boîte. Cliquer sur un type remplace le bloc courant en
conservant son contenu inline. L'item est masqué pour les blocs non-texte
(image, séparateur). Le filtrage respecte la prop `enabledBlocks`.
- **Dupliquer** — insère une copie du bloc juste en dessous (nouvel `id`).
- **Supprimer** — retire le bloc (équivalent à `Backspace` au début d'un bloc
vide), avec focus replacé sur le bloc précédent.
@@ -175,7 +175,9 @@ Un clic sur la poignée `DragDropVerticalIcon` ouvre un menu déroulant
Le drag (`mousedown` + déplacement) et le clic (ouverture du menu) cohabitent
sur le même bouton : si un `dragstart` réel se produit, un drapeau interne
(`justDraggedRef`) supprime l'ouverture du menu lors du `click` qui suit.
Sinon (clic sans déplacement), le menu s'ouvre normalement.
Sinon (clic sans déplacement), le menu s'ouvre normalement. Les dropdowns
sont des composants maison (pas de Headless UI ici) car `MenuButton` ouvrait
sur `pointerdown`, ce qui empêchait le clic-maintenu nécessaire au drag.
## Étendre — enregistrer un bloc custom