refactor(BlockEditor): replace drag handle button with headless ui menu

- add context menu on drag handle with transform, duplicate and delete actions
- introduce `MenuOpenSync` helper to keep handle visible while menu is open
- pass `onTransformBlock`, `onDuplicateBlock`, `onDeleteBlock` and `enabledBlocks` props to Block
- compute `transformOptions` via `useMemo` filtering allowed text block types
- update BlockEditor to wire new block action handlers down to each Block
- update README to document new block action props and menu behavior
This commit is contained in:
2026-04-25 20:29:18 -04:00
parent 515b95c8d3
commit 53ace7fc1f
3 changed files with 155 additions and 17 deletions
+19 -1
View File
@@ -152,12 +152,30 @@ En mode sélection multi-blocs :
Chaque bloc affiche au survol :
- une poignée `Add01Icon` pour insérer un bloc en dessous (ouvre le slash menu)
- une poignée `DragDropVerticalIcon` pour glisser-déposer (réordonner)
- une poignée `DragDropVerticalIcon` à double rôle : presser-glisser pour réordonner, simple clic pour ouvrir le menu d'actions du bloc
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 en** — section 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. La section est
masquée 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.
Le drag (`mousedown` + déplacement) et le clic (ouverture du menu) cohabitent
sur le même bouton : si le pointeur bouge entre `mousedown` et `mouseup`, le
navigateur n'émet pas de `click` et le menu reste fermé.
## Étendre — enregistrer un bloc custom
```js