如何使用带有 Lexical 主题的内联 css 而不是类名

问题描述 投票:0回答:1

我正在构建一个电子邮件客户端,它使用词法将富文本转换为 HTML,使用

$generateHtmlFromNodes
。我已在
initialConfig
.

的词法主题属性中指定了 Tailwindcss 类名称
  const theme: EditorThemeClasses = {
    paragraph: 'text-base mb-1',
    center: 'text-center text-blue-200',
    list: {
      nested: {
        listitem: 'list-disc',
      },
      ol: 'list-decimal',
      ul: 'list-disc',
      listitem: 'list-inside',
    },
    text: {
      bold: 'font-bold',
      italic: 'italic',
      underline: 'underline',
      strikethrough: 'line-through',
      underlineStrikethrough: 'line-through underline',
    },
    link: 'text-blue-500 hover:text-blue-600',
    image: 'object-contain flex flex-row w-2/3 p-4 h-auto',
  };

  const initialConfig = {
    namespace: 'MyEditor',
    editable: true,
    nodes: [ImageNode, ListNode, ListItemNode],
    theme,
    onError(error) {
      throw error;
    },
  };

我能够获得具有正确类名的完全可渲染的 html,但是当发送电子邮件时,CDN 标记要么从电子邮件中剥离,要么无法正确转换样式。

有没有办法在 Lexical

initialConfig
或使用
$generateHtmlFromNodes
时更喜欢内联 css 而不是类名?

css reactjs html-email lexicaljs
1个回答
0
投票

有一个专门的页面关于 HTML 的序列化和反序列化

您可以在初始配置中传递自定义导出函数并更改导出的 html 元素

 const initialConfig: InitialConfigType = {
    namespace: 'Rich-Text-Editor',
    theme,
    onError: (error) => console.error(error),
    nodes: [ListNode, ListItemNode],
    html: {
        export: htmlExportMap
    }
};

htmlExportMap.ts

import { ListNode, ListItemNode } from '@lexical/list';
import { DOMExportOutputMap, isHTMLElement, TextNode } from 'lexical';

export const htmlExportMap: DOMExportOutputMap = new Map();

// Text Node Export
htmlExportMap.set(TextNode, (editor, t) => {
    const target = t as TextNode;
    const node = target.exportDOM(editor);
    const { element } = node;

    if (isHTMLElement(element)) {
        if (target.hasFormat('bold')) {
            const el = element.querySelector('strong') ?? element;
            el.style.fontWeight = 'bold';
            el.removeAttribute('class');
        }
        if (target.hasFormat('italic')) {
            const el = element.querySelector('i') ?? element;
            el.style.fontStyle = 'italic';
            el.removeAttribute('class');
        }
        if (target.hasFormat('underline')) {
            const el = element.querySelector('u') ?? element;
            el.style.textDecorationLine = 'underline';
            el.removeAttribute('class');
        }
    }

    return node;
});

// List Node Export
htmlExportMap.set(ListNode, (editor, t) => {
    const target = t as ListNode;
    const node = target.exportDOM(editor);
    const { element } = node;

    if (isHTMLElement(element)) {
        const format = target.getListType();
        switch (format) {
            case 'bullet':
                element.style.listStyleType = 'disc';
                element.removeAttribute('class');
                break;
        }
    }

    return node;
});

// List Item Node Export
htmlExportMap.set(ListItemNode, (editor, t) => {
    const target = t as TextNode;
    const node = target.exportDOM(editor);
    const { element } = node;

    if (isHTMLElement(element)) {
        element.style.marginInline = '2rem';
        element.removeAttribute('class');
    }

    return node;
});

具有导出功能

<p dir="ltr">
    <u style="text-decoration-line: underline;">
        <i style="font-style: italic;">
            <b><strong style="white-space: pre-wrap; font-weight: bold; color: red;">hey there</strong></b>
        </i>
    </u>
</p>
<p dir="ltr"><br /></p>
<ul style="list-style-type: disc;">
    <li value="1" style="margin-inline: 2rem;"><span style="white-space: pre-wrap;">List 1</span></li>
    <li value="2" style="margin-inline: 2rem;"><span style="white-space: pre-wrap;">List 2</span></li>
    <li value="3" style="margin-inline: 2rem;"><span style="white-space: pre-wrap;">List 3</span></li>
</ul>
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.