diff --git a/packages/lexical-devtools-core/src/generateContent.ts b/packages/lexical-devtools-core/src/generateContent.ts index b08eb2ec777..5e431558d26 100644 --- a/packages/lexical-devtools-core/src/generateContent.ts +++ b/packages/lexical-devtools-core/src/generateContent.ts @@ -67,6 +67,8 @@ const FORMAT_PREDICATES = [ node.hasFormat('superscript') && 'Superscript', (node: TextNode | RangeSelection) => node.hasFormat('underline') && 'Underline', + (node: TextNode | RangeSelection) => + node.hasFormat('highlight') && 'Highlight', ]; const FORMAT_PREDICATES_PARAGRAPH = [ @@ -78,6 +80,7 @@ const FORMAT_PREDICATES_PARAGRAPH = [ (node: ParagraphNode) => node.hasTextFormat('subscript') && 'Subscript', (node: ParagraphNode) => node.hasTextFormat('superscript') && 'Superscript', (node: ParagraphNode) => node.hasTextFormat('underline') && 'Underline', + (node: ParagraphNode) => node.hasTextFormat('highlight') && 'Highlight', ]; const DETAIL_PREDICATES = [ diff --git a/packages/lexical-playground/__tests__/e2e/CopyAndPaste/html/TextFormatHTMLCopyAndPaste.spec.mjs b/packages/lexical-playground/__tests__/e2e/CopyAndPaste/html/TextFormatHTMLCopyAndPaste.spec.mjs index 4a6363168f6..c957e2ed59e 100644 --- a/packages/lexical-playground/__tests__/e2e/CopyAndPaste/html/TextFormatHTMLCopyAndPaste.spec.mjs +++ b/packages/lexical-playground/__tests__/e2e/CopyAndPaste/html/TextFormatHTMLCopyAndPaste.spec.mjs @@ -70,4 +70,39 @@ test.describe('HTML CopyAndPaste', () => { `, ); }); + + test('Copy + paste html with highlight formatting', async ({ + page, + isPlainText, + }) => { + test.skip(isPlainText); + await focusEditor(page); + const clipboardData = { + 'text/html': `

BoldHighlightBold&Highlight

`, + }; + await pasteFromClipboard(page, clipboardData); + await assertHTML( + page, + html` +

+ + Bold + + + Highlight + + + + Bold&Highlight + + +

+ `, + ); + }); }); diff --git a/packages/lexical-playground/src/images/icons/highlighter.svg b/packages/lexical-playground/src/images/icons/highlighter.svg new file mode 100644 index 00000000000..01d88ddeac6 --- /dev/null +++ b/packages/lexical-playground/src/images/icons/highlighter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/lexical-playground/src/index.css b/packages/lexical-playground/src/index.css index a6c9d65c267..1728fe26053 100644 --- a/packages/lexical-playground/src/index.css +++ b/packages/lexical-playground/src/index.css @@ -406,6 +406,10 @@ i.superscript { background-image: url(images/icons/type-superscript.svg); } +i.highlight { + background-image: url(images/icons/highlighter.svg); +} + i.link { background-image: url(images/icons/link.svg); } diff --git a/packages/lexical-playground/src/plugins/ToolbarPlugin/index.tsx b/packages/lexical-playground/src/plugins/ToolbarPlugin/index.tsx index b32d841c7ec..4478e606958 100644 --- a/packages/lexical-playground/src/plugins/ToolbarPlugin/index.tsx +++ b/packages/lexical-playground/src/plugins/ToolbarPlugin/index.tsx @@ -539,6 +539,7 @@ export default function ToolbarPlugin({ const [isStrikethrough, setIsStrikethrough] = useState(false); const [isSubscript, setIsSubscript] = useState(false); const [isSuperscript, setIsSuperscript] = useState(false); + const [isHighlight, setIsHighlight] = useState(false); const [isCode, setIsCode] = useState(false); const [canUndo, setCanUndo] = useState(false); const [canRedo, setCanRedo] = useState(false); @@ -585,6 +586,7 @@ export default function ToolbarPlugin({ setIsStrikethrough(selection.hasFormat('strikethrough')); setIsSubscript(selection.hasFormat('subscript')); setIsSuperscript(selection.hasFormat('superscript')); + setIsHighlight(selection.hasFormat('highlight')); setIsCode(selection.hasFormat('code')); setIsRTL($isParentElementRTL(selection)); @@ -1052,6 +1054,16 @@ export default function ToolbarPlugin({ Superscript + { + activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND, 'highlight'); + }} + className={'item ' + dropDownActiveClass(isHighlight)} + title="Highlight" + aria-label="Format text with a highlight"> + + Highlight + ({ + conversion: convertTextFormatElement, + priority: 0, + }), s: () => ({ conversion: convertTextFormatElement, priority: 0, @@ -1284,6 +1288,7 @@ const nodeNameToTextFormat: Record = { code: 'code', em: 'italic', i: 'italic', + mark: 'highlight', s: 'strikethrough', strong: 'bold', sub: 'subscript',