feat(BlockEditor): add clear formatting button to inline toolbar

- add `removeAllMarks` function to inline/types.js
- implement `applyRemoveAllMarks` handler in BlockEditor client
- add `TextClearIcon` button with separator in Toolbar component
- expose `onClearMarks` prop on InlineToolbar
- update README to document new clear formatting action
This commit is contained in:
2026-04-25 19:23:45 -04:00
parent 741bf39a39
commit 30cd0bbd81
5 changed files with 44 additions and 5 deletions
@@ -1,7 +1,7 @@
'use client';
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
import { TextColorIcon, HighlighterIcon, Link02Icon, CodeSimpleIcon } from '@zen/core/shared/icons';
import { TextColorIcon, HighlighterIcon, Link02Icon, CodeSimpleIcon, TextClearIcon } from '@zen/core/shared/icons';
import { INLINE_COLORS, INLINE_COLOR_KEYS, markKey } from './types.js';
// Toolbar flottant de formatage. Affiché tant qu'une sélection non-vide
@@ -23,7 +23,7 @@ const SIMPLE_BUTTONS = [
{ type: 'code', label: <CodeSimpleIcon width={15} height={15} />, title: 'Code (Ctrl+E)', className: '' },
];
export default function InlineToolbar({ rect, activeMarks, onToggleMark, onPinChange, usedColors }) {
export default function InlineToolbar({ rect, activeMarks, onToggleMark, onClearMarks, onPinChange, usedColors }) {
const ref = useRef(null);
const [pos, setPos] = useState({ top: 0, left: 0, flipped: false });
const [popover, setPopover] = useState(null); // 'color' | 'highlight' | 'link' | null
@@ -146,6 +146,18 @@ export default function InlineToolbar({ rect, activeMarks, onToggleMark, onPinCh
<Link02Icon width={16} height={16} />
</button>
<span className="mx-1 w-px h-5 bg-neutral-200 dark:bg-neutral-700" aria-hidden />
<button
type="button"
title="Effacer le formatage"
onMouseDown={(e) => e.preventDefault()}
onClick={() => onClearMarks?.()}
className="w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800"
>
<TextClearIcon />
</button>
{popover === 'color' && (
<ColorGrid
mode="text"
@@ -296,6 +296,10 @@ export function applyMark(nodes, start, end, mark) {
return mapRange(nodes, start, end, n => addMarkToNode(n, mark));
}
export function removeAllMarks(nodes, start, end) {
return mapRange(nodes, start, end, n => makeNode(n.text));
}
export function removeMark(nodes, start, end, type) {
return mapRange(nodes, start, end, n => removeMarkFromNode(n, type));
}