refactor(BlockEditor): replace emoji icons with react icon components and add free color picker support

- update blockRegistry to accept ReactNode icons instead of emoji strings
- replace emoji icons in all built-in block types with icon components from shared icons
- add `isHexColor` and `collectUsedColors` helpers to inline/types.js
- extend `color` and `highlight` marks to accept hex color strings in addition to palette keys
- pass `usedColors` (collected from document) to InlineToolbar
- update InlineToolbar color popover to show used colors and a free color input
- add new icons to shared icons index
- update README to reflect icon, color, and toolbar popover changes
This commit is contained in:
2026-04-25 18:52:59 -04:00
parent 3f93503996
commit 219fb36da1
17 changed files with 311 additions and 45 deletions
+12 -7
View File
@@ -60,11 +60,13 @@ Chaque nœud porte optionnellement des **marks** (formatage).
| `strike` | — | `<s>` |
| `code` | — | `<code>` (monospace, fond gris) |
| `link` | `href: string` | `<a href>` (target="_blank") |
| `color` | `color: 'blue' \| 'green' \| 'amber' \| 'red'` | couleur du texte |
| `highlight` | `color: 'blue' \| 'green' \| 'amber' \| 'red'` | surlignage de fond |
| `color` | `color: <key> \| '#rrggbb'` | couleur du texte |
| `highlight` | `color: <key> \| '#rrggbb'` | surlignage de fond |
Les couleurs sont des **clés de palette** (pas de hex libre) — résolues vers
les classes Tailwind du DESIGN system. Voir `inline/types.js:INLINE_COLORS`.
Le champ `color` accepte **soit** une clé de palette (`blue`, `green`, `amber`,
`red`) — résolue vers les classes Tailwind du DESIGN system —, **soit** une
string hex `#rrggbb` choisie par l'utilisateur, appliquée via `style` inline.
Voir `inline/types.js:INLINE_COLORS` et `isHexColor`.
Le contenu vide est `[]` (jamais `[{type:'text', text:''}]`).
@@ -75,6 +77,7 @@ import {
inlineLength, inlineToPlainText, inlineFromText,
sliceInline, concatInline, applyMark, toggleMark,
marksAtOffset, marksInRange, INLINE_COLORS,
isHexColor, collectUsedColors,
} from '@zen/core/shared/components/BlockEditor';
```
@@ -118,8 +121,10 @@ Quand une sélection non-vide existe dans un bloc, un toolbar flottant
apparaît au-dessus. Il propose :
- **B I U S `</>`** — marks simples (toggle)
- **A** — couleur du texte (popover de la palette)
- **◐** — surlignage (popover)
- **A** — couleur du texte (popover : palette par défaut + couleurs déjà
utilisées dans le document + bouton `+` pour une couleur libre via
`<input type="color">`)
- **◐** — surlignage (même structure de popover)
- **🔗** — lien (popover avec input URL ; ✕ pour retirer)
L'état actif est calculé à partir des marks **communes à toute la plage**
@@ -158,7 +163,7 @@ import { registerBlock, newBlockId } from '@zen/core/shared/components/BlockEdit
registerBlock({
type: 'kpi',
label: 'KPI',
icon: '📊',
icon: <ChartIcon width={18} height={18} />,
keywords: ['kpi', 'metric', 'stat'],
isText: false,
create: () => ({ id: newBlockId(), type: 'kpi', value: 0 }),