ExtendedTextNode

2.0/email-builder
Lei OT 10 months ago
parent 546aa729b9
commit af8fb09244

@ -32,15 +32,17 @@ import ImagesPlugin from './plugins/ImagesPlugin';
import InlineImagePlugin from './plugins/InlineImagePlugin';
import { ImageNode } from './nodes/ImageNode';
import {InlineImageNode} from './nodes/InlineImageNode/InlineImageNode';
import { ExtendedTextNode } from './nodes/ExtendedTextNode';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
// import { useLexicalEditable } from '@lexical/react/useLexicalEditable';
import {TablePlugin} from '@lexical/react/LexicalTablePlugin';
import TableCellResizer from './plugins/TableCellResizer';
import {useLexicalEditable} from '@lexical/react/useLexicalEditable';
import { $getRoot, $getSelection, $createParagraphNode } from 'lexical';
import { TextNode, $getRoot, $getSelection, $createParagraphNode } from 'lexical';
import { $generateHtmlFromNodes, $generateNodesFromDOM, } from '@lexical/html';
// import { } from '@lexical/clipboard';
import { isEmpty } from '@/utils/commons';
@ -57,10 +59,17 @@ const editorConfig = {
theme: ExampleTheme,
// Handling of errors during update
onError(error) {
console.log(error)
throw error;
},
// Any custom nodes go here
nodes: [
ExtendedTextNode,
{
replace: TextNode,
with: (node) => new ExtendedTextNode(node.__text),
withKlass: ExtendedTextNode,
},
HeadingNode,
ListNode,
ListItemNode,
@ -159,6 +168,8 @@ export default function Editor({ isRichText, isDebug, editorRef, onChange, defau
<AutoLinkPlugin />
<LinkPlugin />
<MarkdownShortcutPlugin transformers={TRANSFORMERS} />
<TablePlugin />
{/* <TableCellResizer /> */}
<TabFocusPlugin />
<TabIndentationPlugin />
<HorizontalRulePlugin />

@ -0,0 +1,129 @@
import {
$applyNodeReplacement,
$isTextNode,
DOMConversion,
DOMConversionMap,
DOMConversionOutput,
NodeKey,
TextNode,
SerializedTextNode,
LexicalNode
} from 'lexical';
export class ExtendedTextNode extends TextNode {
constructor(text: string, key?: NodeKey) {
super(text, key);
}
static getType(): string {
return 'extended-text';
}
static clone(node: ExtendedTextNode): ExtendedTextNode {
return new ExtendedTextNode(node.__text, node.__key);
}
static importDOM(): DOMConversionMap | null {
const importers = TextNode.importDOM();
return {
...importers,
code: () => ({
conversion: patchStyleConversion(importers?.code),
priority: 1
}),
em: () => ({
conversion: patchStyleConversion(importers?.em),
priority: 1
}),
span: () => ({
conversion: patchStyleConversion(importers?.span),
priority: 1
}),
strong: () => ({
conversion: patchStyleConversion(importers?.strong),
priority: 1
}),
sub: () => ({
conversion: patchStyleConversion(importers?.sub),
priority: 1
}),
sup: () => ({
conversion: patchStyleConversion(importers?.sup),
priority: 1
}),
};
}
static importJSON(serializedNode: SerializedTextNode): TextNode {
return TextNode.importJSON(serializedNode);
}
isSimpleText() {
return this.__type === 'extended-text' && this.__mode === 0;
}
exportJSON(): SerializedTextNode {
return {
...super.exportJSON(),
type: 'extended-text',
version: 1,
}
}
}
export function $createExtendedTextNode(text: string): ExtendedTextNode {
return $applyNodeReplacement(new ExtendedTextNode(text));
}
export function $isExtendedTextNode(node: LexicalNode | null | undefined): node is ExtendedTextNode {
return node instanceof ExtendedTextNode;
}
function patchStyleConversion(
originalDOMConverter?: (node: HTMLElement) => DOMConversion | null
): (node: HTMLElement) => DOMConversionOutput | null {
return (node) => {
const original = originalDOMConverter?.(node);
if (!original) {
return null;
}
const originalOutput = original.conversion(node);
if (!originalOutput) {
return originalOutput;
}
const background = node.style.background;
const backgroundColor = node.style.backgroundColor;
const color = node.style.color;
const fontFamily = node.style.fontFamily;
const fontWeight = node.style.fontWeight;
const fontSize = node.style.fontSize;
const textDecoration = node.style.textDecoration;
return {
...originalOutput,
forChild: (lexicalNode, parent) => {
const originalForChild = originalOutput?.forChild ?? ((x) => x);
const result = originalForChild(lexicalNode, parent);
if ($isTextNode(result)) {
const style = [
background ? `background: ${background}` : null,
backgroundColor ? `background-color: ${backgroundColor}` : null,
color ? `color: ${color}` : null,
fontFamily ? `font-family: ${fontFamily}` : null,
fontWeight ? `font-weight: ${fontWeight}` : null,
fontSize ? `font-size: ${fontSize}` : null,
textDecoration ? `text-decoration: ${textDecoration}` : null,
]
.filter((value) => value != null)
.join('; ');
if (style.length) {
return result.setStyle(style);
}
}
return result;
}
};
};
}
Loading…
Cancel
Save