219fb36da1
- 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
48 lines
2.0 KiB
JavaScript
48 lines
2.0 KiB
JavaScript
// Registre extensible des types de blocs.
|
|
// Les blocs built-in s'enregistrent dans defaultBlocks.js (chargé par index.js).
|
|
// Les consommateurs peuvent appeler `registerBlock` pour ajouter leurs propres types.
|
|
//
|
|
// Forme d'une définition de bloc :
|
|
// {
|
|
// type: string, // id unique (ex: 'paragraph', 'my_custom')
|
|
// label: string, // libellé affiché dans le slash menu
|
|
// icon: ReactNode, // élément React rendu dans le slash menu (typiquement une icône de `@zen/core/shared/icons`)
|
|
// keywords: string[], // termes de recherche pour le slash menu
|
|
// shortcut?: string, // préfixe markdown qui convertit (ex: '# ', '- ')
|
|
// shortcutTransform?: (block, match) => block, // optionnel : transforme un bloc existant
|
|
// create: (init?) => Block, // construit un nouveau bloc
|
|
// isText: boolean, // true si le bloc a un contentEditable de texte
|
|
// textTag?: string, // pour info / rendu en mode display
|
|
// textClassName?: string, // classes appliquées au contentEditable
|
|
// placeholder?: string, // texte fantôme quand le bloc est vide et focus
|
|
// renderPrefix?: (ctx) => ReactNode, // pour les listes (puce, numéro)
|
|
// Component?: ReactComponent, // pour blocs non-texte ; reçoit { block, onChange, disabled }
|
|
// }
|
|
|
|
const registry = new Map();
|
|
|
|
export function registerBlock(def) {
|
|
if (!def || typeof def.type !== 'string') {
|
|
throw new Error('registerBlock: `type` is required');
|
|
}
|
|
if (typeof def.create !== 'function') {
|
|
throw new Error(`registerBlock(${def.type}): \`create\` is required`);
|
|
}
|
|
registry.set(def.type, def);
|
|
}
|
|
|
|
export function getBlockDef(type) {
|
|
return registry.get(type) || null;
|
|
}
|
|
|
|
export function listBlocks() {
|
|
return Array.from(registry.values());
|
|
}
|
|
|
|
export function isBlockText(type) {
|
|
const def = registry.get(type);
|
|
return Boolean(def?.isText);
|
|
}
|
|
|
|
export const DEFAULT_BLOCK_TYPE = 'paragraph';
|